﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CdcSoftware.Pivotal.Applications.Core.Common;
using CdcSoftware.Pivotal.Applications.Core.Data;
using CdcSoftware.Pivotal.Engine;
using CdcSoftware.Pivotal.Engine.Types.ServerTasks;
using CdcSoftware.Pivotal.Applications.Core.Server;
using CdcSoftware.Pivotal.Engine.Types.DataTemplates;
using System.Data;
using CdcSoftware.Pivotal.Engine.Types.Reports;
using CdcSoftware.Pivotal.Engine.Mail;
using CdcSoftware.Pivotal.Engine.Types.Database;
using CdcSoftware.Pivotal.Engine.DataServices;

namespace Pcm.Inventory.Server.FormTasks
{
    public class RE_Inventory_Transfer : AbstractDataTemplateServerTask
    {
        public RE_Inventory_Transfer()
        {
            this.DefaultResourceBundleName = "RE_Email";
        }
        #region Constants

        const string REInventoryTransferIdFieldName = "RE_Inventory_Transfer_Id";
        const string ProductBarCodeFieldName = "Product_Barcode";
        const string QuantityIssuedFieldName = "Quantity_Issued";
        const string QuantityReceivedFieldName = "Quantity_Received";
        const string QuantityOpenFieldName = "Quantity_Open";
        const string ProductIdFieldName = "Product_Id";
        const string ProductSKUIdFieldName = "Product_SKU_Id";
        const string FromStorageLocationIdFieldName = "From_Storage_Location_Id";
        const string ToStorageLocationIdFieldName = "To_Storage_Location_Id";
        const string REInvTransferProductTableName = "RE_Inv_Transfer_Product";
        const string TransferQuantityFieldName = "Transfer_Quantity";
        const string ReceivedQuantityFieldName = "Received_Quantity";
        const string RnDescriptorFieldName = "Rn_Descriptor";
        const string ProductTableName = "Product";
        const string Symbol = "@";
        const string ColorFieldName = "Color";
        const string SizeFieldName = "Size";
        //RE_Color & RE_Size table
        const string REColorTableName = "RE_Color";
        const string RESizeTableName = "RE_Size";
        const string DescriptionFieldName = "Description";
        const string ReceivedFieldName = "Received";
        const string StatusFieldName = "Status";

        public struct OrderType
        {
            public const string Sale = "Sale";
            public const string Refund = "Refund";
            public const string Exchange = "Exchange";
        }

        const string VoidOrderStatus = "Void";

        #endregion

        #region Abstract Data Template Methods

        protected override DataSet LoadData(DataTemplate dataTemplate, Id rowId, ParameterList parameters)
        {
            return base.LoadData(dataTemplate, rowId, parameters);
        }

        protected override Id AddData(DataTemplate dataTemplate, DataSet data, ParameterList parameters)
        {
            try
            {
                DataRow primaryRow = data.Tables[0].Rows[0];
                DataTable invTransferProducts = data.Tables["RE_Inv_Transfer_Product_RE_Inv"];
                Id recordId = null;
                if (dataTemplate.Name == "RE_RMA")
                {   
                    //List<Id> supplierId = (from myRow in invTransferProducts.AsEnumerable()
                    //                  select Id.Create(myRow.Field<byte[]>("Product_Id__RE_Supplier_Id"))).Distinct().ToList();
                    recordId = this.SystemServer.DataService.AddDataDirect(dataTemplate, data, parameters);
                    //this.SystemServer.DataService.LoadDataDirect(dataTemplate, recordId, parameters);
                    //if (supplierId.Count() == 1)
                    //{
                    //    updatePrimary(recordId, Id.Create(supplierId[0]));
                    //    processInventory("RMA", "Issue", recordId);
                    //    CreateReport(recordId);
                    //}
                    //else
                    //{
                    //    for (int i = 0; i < supplierId.Count() - 1; i++)
                    //    {
                    //        CreateInventoryTransfer(primaryRow, Id.Create(supplierId[i]), recordId);
                    //    }
                    //    updatePrimary(recordId, Id.Create(supplierId[supplierId.Count()-1]));
                    //    processInventory("RMA", "Issue", recordId);
                    //    CreateReport(recordId);
                    //}

                    //foreach (object tempId in supplierId)
                    //{
                    //    CreateInventoryTransfer(primaryRow, Id.Create(tempId),recordId);
                    //}
                    return recordId;
                    //return base.AddData(dataTemplate, data, parameters);
                }
                //else if (dataTemplate.Name == "RE_Goods_Issue") 
                //{   
                //    recordId= base.AddData(dataTemplate, data, parameters);

                //    if(String.Equals(TypeConvert.ToString(primaryRow["Status"]),"Issued"))
                //    {
                //        processInventory("Inventory Transfer", "Issued", recordId);
                //    }
                //    return recordId;
                //}
                else
                {
                    if (data.Tables[0].Rows[0]["DisconnOrig_Goods_Issue_Id"] != DBNull.Value)
                    {
                        object origGoodsIssueId = data.Tables[0].Rows[0]["DisconnOrig_Goods_Issue_Id"];
                        bool deletePendingItems = TypeConvert.ToBoolean(data.Tables[0].Rows[0]["DisconnDelete_PendingItems"]);
                        if (deletePendingItems)
                        {
                            //DeletePendingInvTransferProductItems(TypeConvert.ToString(data.Tables[0].Rows[0]["DisconnPendingItemsId"]));
                            //Save the original goods Issue record so that Total Quantity gets updated
                            DataTable inventTransfer = DefaultDataAccess.GetDataTable("RE_Inventory_Transfer", Id.Create(origGoodsIssueId),
                                                        new string[] { TransferQuantityFieldName, StatusFieldName, ReceivedQuantityFieldName });
                            if (inventTransfer != null && inventTransfer.Rows.Count > 0)
                            {
                                DataTable transferProduct = this.DefaultDataAccess.GetDataTable("RE All Inv Transfer Product for InvTransfer Id?", Id.Create(origGoodsIssueId),
                                       new string[] { QuantityIssuedFieldName, ReceivedFieldName, QuantityReceivedFieldName });
                                Int32 totalIssuedQuantity = 0;
                                Int32 totalReceivedQuantity = 0;
                                bool received = true;
                                if (transferProduct != null && transferProduct.Rows.Count > 0)
                                {
                                    for (int i = 0; i < transferProduct.Rows.Count; i++)
                                    {
                                        if (TypeConvert.ToInt32(transferProduct.Rows[i][QuantityIssuedFieldName]) > 0)
                                            totalIssuedQuantity = totalIssuedQuantity + TypeConvert.ToInt32(transferProduct.Rows[i][QuantityIssuedFieldName]);

                                        if (TypeConvert.ToBoolean(transferProduct.Rows[i][ReceivedFieldName]) == false)
                                            received = false;

                                        if (TypeConvert.ToInt32(transferProduct.Rows[i][QuantityReceivedFieldName]) > 0)
                                            totalReceivedQuantity = totalReceivedQuantity + TypeConvert.ToInt32(transferProduct.Rows[i][QuantityReceivedFieldName]);
                                    }
                                    inventTransfer.Rows[0][TransferQuantityFieldName] = totalIssuedQuantity;
                                    inventTransfer.Rows[0][ReceivedQuantityFieldName] = totalReceivedQuantity;

                                    //VT: This will happen when we are creating New GI from Issue form.  After deleting Transfer Product which are chosen for
                                    //the new Issue form we need to check for the Received status & update the 'Inventory Transfer' accordingly.
                                    if (received)
                                        inventTransfer.Rows[0][StatusFieldName] = "Received";

                                    DefaultDataAccess.SaveDataTable(inventTransfer);
                                }
                            }
                        }
                    }
                    return base.AddData(dataTemplate, data, parameters);
                }
            }
            catch (Exception exc)
            {
                throw new PivotalApplicationCoreException(exc.Message, exc);
            }
        }

        protected override DataSet NewData(DataTemplate dataTemplate, ParameterList parameters)
        {
            try
            {
                DataSet invTransferDS = this.SystemServer.DataService.NewDataDirect(dataTemplate, parameters);

                //Set the Defualt column values
                this.TransitionPointParameter.ParameterList = parameters;
                if (!this.TransitionPointParameter.HasValidParameters())
                {
                    this.TransitionPointParameter.Construct();
                }
                else
                {
                    this.TransitionPointParameter.SetDefaultColumns(invTransferDS.Tables[0].Rows[0]);
                    this.TransitionPointParameter.WarningMessage = string.Empty;
                }
                if (this.TransitionPointParameter.UserDefinedParametersNumber > 0)
                {
                    //Inventory transfer product secondary (pending items) will be created only if we get userdefined values 
                    //sent from the client during 'On click of New GI button
                    if (TypeConvert.ToString(this.TransitionPointParameter.GetUserDefinedParameter(1)) == "CreateNewGIWithPendingItems")
                    {
                        #region CreateNewGIWithPendingItems

                        object[] transferProductId = (object[])this.TransitionPointParameter.GetUserDefinedParameter(2);
                        if (transferProductId.Length > 0)
                        {
                            DataTable transferProdDT = (DataTable)invTransferDS.Tables[1];
                            DataRow dRow = null;
                            object idValue = DBNull.Value;
                            string[] stringArray = new string[] { };
                            stringArray = new string[transferProductId.Length];
                            string productIdArray = string.Empty;
                            for (int i = 0; i < transferProductId.Length; i++)
                            {
                                dRow = transferProdDT.NewRow();

                                //SetInventoryTransferProductValues(ref dRow, Id.Create(transferProductId.GetValue(i)));
                                stringArray[i] = Id.Create(transferProductId.GetValue(i)).ToString();
                                if (productIdArray == string.Empty)
                                    productIdArray = Id.Create(transferProductId.GetValue(i)).ToString();
                                else
                                    productIdArray = productIdArray + "," + Id.Create(transferProductId.GetValue(i)).ToString();

                                transferProdDT.Rows.Add(dRow);
                            }
                            invTransferDS.Tables[0].Rows[0]["DisconnOrig_Goods_Issue_Id"] = Id.Create(this.TransitionPointParameter.GetUserDefinedParameter(3)).ToByteArray();
                            invTransferDS.Tables[0].Rows[0]["DisconnDelete_PendingItems"] = true;
                            invTransferDS.Tables[0].Rows[0]["DisconnPendingItemsId"] = productIdArray;
                            invTransferDS.AcceptChanges();

                        }
                        #endregion
                    }
                    else if (TypeConvert.ToString(this.TransitionPointParameter.GetUserDefinedParameter(1)) == "CreateCopyGoodsIssue")
                    {
                        #region CreateCopyGoodsIssue

                        DataTable transferProdDT = (DataTable)invTransferDS.Tables[1];
                        //this.CreateCopyofTransferProducts(ref transferProdDT, Id.Create(this.TransitionPointParameter.GetUserDefinedParameter(3)));
                        invTransferDS.AcceptChanges();

                        #endregion
                    }
                }
                else
                {
                    #region This block is for a Normal New GI
                    if (dataTemplate.Name == "RE_Goods_Issue")
                    {
                        object storeId = this.DefaultDataAccess.SqlIndex("Employee", "RE_Store_Id", this.SystemServer.UserProfile.EmployeeId);
                        object storageLocationId = DBNull.Value;

                        DataTable storageLoc = this.DefaultDataAccess.GetDataTable("RE Storage Location For Primary Locations ?", new object[] { storeId }, 
                            new string[] { "RE_Storage_Location_Id" });
                        if (storageLoc != null && storageLoc.Rows.Count > 0)
                        {
                            invTransferDS.Tables[0].Rows[0]["From_Storage_Location_Id"] = storageLoc.Rows[0]["RE_Storage_Location_Id"];
                            invTransferDS.Tables[0].Rows[0]["DisconnStore_Value"] = storeId;
                            invTransferDS.Tables[0].Rows[0]["Disconn_StoreDesc"] = TypeConvert.ToString(DefaultDataAccess.SqlIndex("RE_Store", "Description", Id.Create(storeId)));
                        }
                    }
                    #endregion
                }
                return invTransferDS;
            }
            catch (Exception exc)
            {
                throw new PivotalApplicationCoreException(exc.Message, exc);
            }
        }

        /// <summary>
        /// Save data.
        /// </summary>
        /// <param name="dataTemplate"></param>
        /// <param name="data"></param>
        /// <param name="parameters"></param>
        protected override void SaveData(DataTemplate dataTemplate, DataSet data, ParameterList parameters)
        {
            try
            {
                DataRow primaryRow = data.Tables[0].Rows[0];
                DataTable invTransferProducts = data.Tables["RE_Inv_Transfer_Product_RE_Inv"];
                this.TransitionPointParameter.ParameterList = parameters;
                base.SaveData(dataTemplate, data, parameters);
                
                if (dataTemplate.Name == "RE_RMA")
                {
                    primaryRow = data.Tables[0].Rows[0];
                    invTransferProducts = data.Tables["RE_Inv_Transfer_Product_RE_Inv"];

                    if(String.Equals(TypeConvert.ToString(primaryRow["Transfer_Type"]),"RMA"))
                    {
                        if (String.Equals(TypeConvert.ToString(primaryRow["RMA_Status"]),"Collected"))
                        {
                            processInventory("RMA", "Collected", primaryRow["RE_Inventory_Transfer_Id"]);
                        }
                        if (String.Equals(TypeConvert.ToString(primaryRow["RMA_Status"]), "Cancelled"))
                        {
                            processInventory("RMA", "Cancelled", primaryRow["RE_Inventory_Transfer_Id"]);
                        }
                    }
                }

                if (dataTemplate.Name == "RE_Goods_Receive")
                {
                    if (String.Equals(TypeConvert.ToString(primaryRow["Transfer_Type"]), "PO Receive"))
                    {
                        processInventory("PO Receive", "Received", primaryRow["RE_Inventory_Transfer_Id"]);
                    }
                    else if (String.Equals(TypeConvert.ToString(primaryRow["Transfer_Type"]), "Inventory Receive"))
                    {
                        processInventory("Inventory Receive", "Received", primaryRow["RE_Inventory_Transfer_Id"]);
                    }
                    else if (String.Equals(TypeConvert.ToString(primaryRow["Transfer_Type"]), "Inventory Transfer"))
                    {
                        processInventory("Inventory Transfer", "Received", primaryRow["RE_Inventory_Transfer_Id"]);
                    }
                }

                //if (dataTemplate.Name == "RE_Goods_Issue")
                //{
                //    if (String.Equals(TypeConvert.ToString(primaryRow["Status"]), "Issued"))
                //    {
                //        processInventory("Inventory Transfer", "Issued",primaryRow["RE_Inventory_Transfer_Id"]);
                //    }
                //}

                /*
                //In GI also we need to create Movement records, only the case when there is an additional item added by the receiving store and Issue store removes that item.
                //Then the issue items and the receive items are exact match and we need to create new Movement record as the status will be set to Received.

                //Also this common code will never get executed for GI as for GI, the status can never be Received.

                //Create Inventory Movements only when the Status is set to Received.
                //Once the status is set to Received and saved, the entire form becomes read-only. So no fear of Movement records getting created again and again.
                if (TypeConvert.ToString(data.Tables[0].Rows[0]["Status"]) == "Received")
                {
                    DataTable transferProdDT;
                    if (this.TransitionPointParameter.UserDefinedParametersNumber != 0)
                        transferProdDT = (DataTable)this.TransitionPointParameter.GetUserDefinedParameter(1);                        
                    else
                        transferProdDT = data.Tables[1];

                    foreach (DataRow dr in transferProdDT.Rows)
                    {
                        //DecideMovement(data.Tables[0].Rows[0][REInventoryTransferIdFieldName], dr);
                    }

                    //if (this.TransitionPointParameter.UserDefinedParametersNumber != 0)
                    //{
                    //    DataTable deletedDT = (DataTable)this.TransitionPointParameter.GetUserDefinedParameter(1);
                    //    if (deletedDT != null && deletedDT.Rows.Count > 0)
                    //    {
                    //        foreach (DataRow dr in deletedDT.Rows)
                    //        {
                    //            DecideMovement(data.Tables[0].Rows[0][REInventoryTransferIdFieldName], dr);
                    //        }
                    //    }
                    //}
                }
                 */
            }
            catch (Exception exc)
            {
                throw new PivotalApplicationCoreException(exc.Message, exc);
            }
        }

        /// <summary>
        /// Decide whether the Movement will be for New row or existing row.
        /// </summary>
        /// <param name="inventoryTransferId"></param>
        /// <param name="dr"></param>
        //private void DecideMovement(object inventoryTransferId, DataRow dr)
        //{
        //    if (TypeConvert.ToBoolean(dr["GR_NewTransfer"]))
        //    {
        //        //Create Movement records for the Newly added Product Transfer in Receive form                               
        //        this.CreateInventoryMovement(inventoryTransferId,
        //                                dr[ProductIdFieldName],
        //                                dr[ProductSKUIdFieldName],
        //                                dr[FromStorageLocationIdFieldName],
        //                                dr[ToStorageLocationIdFieldName],
        //                                TypeConvert.ToInt32(dr[QuantityReceivedFieldName]),
        //                                false, false, "Transfer");
        //    }
        //    else
        //    {
        //        //Create Movement for the issued records (which is scanned in Receive form)
        //        this.CreateInventoryMovement(inventoryTransferId,
        //                                dr[ProductIdFieldName],
        //                                dr[ProductSKUIdFieldName],
        //                                dr[FromStorageLocationIdFieldName],
        //                                dr[ToStorageLocationIdFieldName],
        //                                TypeConvert.ToInt32(dr[QuantityReceivedFieldName]),
        //                                false, true, "Transfer");
        //    }
        //}
        #endregion

        #region Private methods
        //<summary>
        // Updates Inventory Based on Direction
        // </summary>
        // <param name="InventoryId">Inventory Record</param>
        // <param name="InventoryId">Inventory Record</param>
        // <param name="Quantity">Quantity value to be added or subtracted from the Inventory</param>

        private void updateInventory(object InventoryId, string Direction,int Quantity)
        {
            try
            {
                using (DataTable Inventory = this.DefaultDataAccess.GetDataTable("RE_Inventory for InventoryId?", new object[] { InventoryId }, new string[] { "Quantity_Actual" }))
                {
                    if (Inventory != null && Inventory.Rows.Count > 0)
                    {
                        if (String.Equals(Direction, "Add"))
                        {
                            Inventory.Rows[0]["Quantity_Actual"] = TypeConvert.ToInt32(Inventory.Rows[0]["Quantity_Actual"]) + Math.Abs(Quantity);
                        }
                        else if (String.Equals(Direction, "Subtract"))
                        {
                            Inventory.Rows[0]["Quantity_Actual"] = TypeConvert.ToInt32(Inventory.Rows[0]["Quantity_Actual"]) - Math.Abs(Quantity);
                        }
                    }
                    this.DefaultDataAccess.SaveDataTable(Inventory);
                }
            }
            catch(Exception ex)
            {
                throw new PivotalApplicationCoreException(ex.Message, ex);
            }
        }

        //<summary>
        // Creates New Product Serial Number record
        // </summary>
        // <param name="Serial_Number">Product Serial Number</param>
        // <param name="Product_Id">Product Id</param>
        // <param name="Article_Number">Article Number</param>
        // <param name="Available_For_Sale"></param>
        // <param name="Storage_Location_Id">Storage Location</param>
        // <param name="Voucher">Voucher</param>
        // <param name="Voucher_Status">Voucher Status</param>

        private object createSerialNumber(string Serial_Number, object Product_Id, string Article_Number, bool Available_For_Sale,
            object Storage_Location, bool voucher, string Voucher_Status)
        {
            try
            {
                using (DataTable newSerialNumber = this.DefaultDataAccess.GetNewDataTable("RE_Product_Serial_No", new string[] { "Serial_Number", "Product_Id", 
                "Article_Number","Available_For_Sale","Storage_Location_Id","Voucher","Voucher_Status","Voucher_Expiry_Date"}))
                {
                    DataRow newSerialNumberRow = newSerialNumber.NewRow();

                    newSerialNumberRow["Serial_Number"] = Serial_Number;
                    newSerialNumberRow["Product_Id"] = Product_Id;
                    newSerialNumberRow["Article_Number"] = Article_Number;
                    newSerialNumberRow["Available_For_Sale"] = Available_For_Sale;
                    newSerialNumberRow["Storage_Location_Id"] = Storage_Location;
                    newSerialNumberRow["Voucher"] = voucher;
                    newSerialNumberRow["Voucher_Status"] = Voucher_Status;
                    newSerialNumberRow["Voucher_Expiry_Date"] = DBNull.Value;

                    newSerialNumber.Rows.Add(newSerialNumberRow);

                    DataTable serialNumber = this.DefaultDataAccess.SaveDataTable(newSerialNumber);

                    return serialNumber.Rows[0]["RE_Product_Serial_No_Id"];
                }
            }
            catch (Exception ex)
            {
                throw new PivotalApplicationCoreException(ex.Message, ex);
            }
        }

        //<summary>
        // Updates Product Serial Number Record
        // </summary>
        // <param name="Serial_Number">Product Serial Number</param>
        // <param name="Product_Id">Product Id</param>
        // <param name="Article_Number">Article Number</param>
        // <param name="Available_For_Sale"></param>
        // <param name="Storage_Location_Id">Storage Location</param>
        // <param name="Voucher">Voucher</param>
        // <param name="Voucher_Status">Voucher Status</param>

        private void updateSerialNumber(string Serial_Number, object Product_Id, string Article_Number, bool Available_For_Sale,
            object Storage_Location, bool voucher, string Voucher_Status,DateTime Voucher_Expiry_Date)
        {
            try
            {
                using (DataTable SerialNumber = this.DefaultDataAccess.GetDataTable("RE_ProductSerialNo based on Serial_Number?Product?", new object[] { Serial_Number,Product_Id },
                    new string[] { "Available_For_Sale", "Storage_Location_Id", "Voucher_Status", "Voucher_Expiry_Date" }))
                {
                    if (SerialNumber != null && SerialNumber.Rows.Count > 0)
                    {
                        SerialNumber.Rows[0]["Available_For_Sale"] = Available_For_Sale;
                        SerialNumber.Rows[0]["Storage_Location_Id"] = Storage_Location;
                        if (voucher)
                            SerialNumber.Rows[0]["Voucher_Status"] = Voucher_Status;
                        if (voucher && Available_For_Sale == false)
                            SerialNumber.Rows[0]["Voucher_Expiry_Date"] = Voucher_Expiry_Date;
                        else if (voucher && Available_For_Sale == true)
                            SerialNumber.Rows[0]["Voucher_Expiry_Date"] = DBNull.Value;
                        this.DefaultDataAccess.SaveDataTable(SerialNumber);
                    }
                }
            }
            catch (Exception ex)
            {
                throw new PivotalApplicationCoreException(ex.Message, ex);
            }
        }

        //<summary>
        // Updates Inventory Transfer Product Record
        // </summary>
        // <param name="Serial_Number">Product Serial Number</param>
        // <param name="Product_Id">Product Id</param>
        // <param name="Article_Number">Article Number</param>
        // <param name="Available_For_Sale"></param>
        // <param name="Storage_Location_Id">Storage Location</param>
        // <param name="Voucher">Voucher</param>
        // <param name="Voucher_Status">Voucher Status</param>
        [TaskExecute]
        private void updateInventoryTransferProduct(object invTransfer,object productId,object serialNumber)
        {
            try
            {
                DataTable invTransferProduct = null;
                if (Convert.IsDBNull(serialNumber))
                {
                    invTransferProduct = this.DefaultDataAccess.GetDataTable("RE Inv Transfer Product for Product?InvTransfer Id?", new object[] { productId, invTransfer },
                        new string[] { "Received", "Quantity_Received" });
                    {
                        if (invTransferProduct != null && invTransferProduct.Rows.Count > 0)
                        {
                            invTransferProduct.Rows[0]["Received"] = true;
                            invTransferProduct.Rows[0]["Quantity_Received"] = 1;
                        }
                    }
                }
                else
                {
                    invTransferProduct = this.DefaultDataAccess.GetDataTable("RE Inv Transfer Product for Product? Serial Number? InvTransfer Id?", new object[] { productId, invTransfer },
                        new string[] { "Received", "Quantity_Received" });
                    if (invTransferProduct != null && invTransferProduct.Rows.Count > 0)
                    {
                        invTransferProduct.Rows[0]["Received"] = true;
                        invTransferProduct.Rows[0]["Quantity_Received"] = 1;
                    }
                }
                this.DefaultDataAccess.SaveDataTable(invTransferProduct);
            }
            catch (Exception ex)
            {
                throw new PivotalApplicationCoreException(ex.Message, ex);
            }
        }

        //<summary>
        // Create Inventory Movement
        // </summary>
        // <param name="Type">Product Serial Number</param>
        // <param name="Sub-Type">Product Id</param>
        // <param name="Inventory_Id">Article Number</param>
        // <param name="Product_Id"></param>
        // <param name="Serialized">Storage Location</param>
        // <param name="SKU">Storage Location</param>
        // <param name="Storage_Location_Id">Voucher</param>
        // <param name="Storage_Location_Code">Voucher Status</param>
        // <param name="Quantity">Voucher Status</param>
        // <param name="Direction">Voucher Status</param>
        // <param name="Reason">Voucher Status</param>
        // <param name="Ref_Order_Id">Voucher Status</param>
        // <param name="Ref_Inventory_Trnsfr_Id">Voucher Status</param>
        // <param name="RE_Product_Serial_No_Id">Voucher Status</param>
        // <param name="Serial_Number">Voucher Status</param>
        // <param name="External_Reference_Number">Voucher Status</param>
        // <param name="RE_Inv_Trnsf_Rec_Batch_Id">Voucher Status</param>

        private void CreateInventoryMovement(string Type,string Subtype,object inventoryId,object productId,bool serialized
            ,string SKU,object StorageLocation,string storageLocationCode,Int32 quantity,string direction,string reason,object refOrderId,
            object refInvTransferId,object productSerialNumberId,string serialNumber,object invTransferRecBatchId)
        {
            try
            {
                string artNumber=string.Empty;
                string prodType=string.Empty;
                bool availableForSale = false;
                string voucherStatus=string.Empty;
                object storageLocation = DBNull.Value;
                object newSerialNumber =DBNull.Value;
                DateTime voucherExpiryDate = DateTime.Now;
                int voucherExpiryMonths;

                object lobID = this.DefaultDataAccess.SqlIndex("Employee", "RE_Line_Of_Business_Id", this.SystemServer.UserProfile.EmployeeId);

                switch (Type)
                {
                    case "Sale":
                        //availableForSale = (((String.Equals(Subtype, "Exchange")))) || String.Equals(Subtype, "Refund")) ? true : false;
                        availableForSale = (String.Equals(direction, "Add")) ? true : false;
                        break;
                    case "RMA":
                        availableForSale = (String.Equals(Subtype, "Issue") || String.Equals(Subtype, "Collect")) ? false : true;
                        break;
                    case "Inventory Transfer":
                        availableForSale = (String.Equals(Subtype, "Received") || String.Equals(Subtype, "Cancel")) ? true : false;
                        break;
                    case "Inventory Receive":
                        availableForSale = (String.Equals(Subtype, "Received")) ? true : false;
                        break;
                    case "Void":
                        availableForSale = (String.Equals(direction, "Add")) ? true : false;
                        break;
                    case "PO Receive":
                        availableForSale = (String.Equals(direction, "Add")) ? true : false;
                        break;
                    default:
                        break;
                }

                switch (Type)
                {
                    case "Sale":
                        //storageLocation = (String.Equals(Subtype, "Exchange") || String.Equals(Subtype, "Refund")) ? StorageLocation : DBNull.Value;
                        storageLocation = (String.Equals(direction, "Add")) ? StorageLocation : DBNull.Value;
                        break;
                    case "RMA":
                        storageLocation = (String.Equals(direction, "Add")) ? StorageLocation : DBNull.Value;
                        break;
                    case "Inventory Transfer":
                        storageLocation = (String.Equals(direction, "Add")) ? StorageLocation : DBNull.Value;
                        break;
                    case "Inventory Receive":
                        storageLocation = (String.Equals(direction, "Add")) ? StorageLocation : DBNull.Value;
                        break;
                    case "Void":
                        //storageLocation = (String.Equals(Subtype, "Exchange") || String.Equals(Subtype, "Refund")) ? StorageLocation : DBNull.Value;
                        storageLocation = (String.Equals(direction, "Add")) ? StorageLocation : DBNull.Value;
                        break;
                    case "PO Receive":
                        //storageLocation = (String.Equals(Subtype, "Exchange") || String.Equals(Subtype, "Refund")) ? StorageLocation : DBNull.Value;
                        storageLocation = (String.Equals(direction, "Add")) ? StorageLocation : DBNull.Value;
                        break;
                    default:
                        break;
                }

                switch (Type)
                {
                    case "Sale":
                        //availableForSale = (((String.Equals(Subtype, "Exchange")))) || String.Equals(Subtype, "Refund")) ? true : false;
                        voucherStatus = (String.Equals(direction, "Add")) ? "In Stock" : "Sold";
                        break;
                    case "Void":
                        voucherStatus = (String.Equals(direction, "Add")) ? "In Stock" : "Sold";
                        break;
                    case "Inventory Receive":
                        voucherStatus = (String.Equals(direction, "Add")) ? "In Stock" : "Sold";
                        break;
                    case "Inventory Transfer":
                        voucherStatus = (String.Equals(Subtype, "Received")) ? "In Stock" : "Sold";
                        break;
                    case "PO Receive":
                        voucherStatus = (String.Equals(direction, "Add")) ? "In Stock" : "Sold";
                        break;
                    default:
                        break;
                }
                DataTable articleNumber = this.DefaultDataAccess.GetDataTable("SFA: Products id equal to ?", new object[] { productId }, new string[] { "RE_Article_Number", "RE_Product_Type" });
                if (articleNumber != null && articleNumber.Rows.Count > 0)
                {
                    artNumber = TypeConvert.ToString(articleNumber.Rows[0]["RE_Article_Number"]);
                    prodType = TypeConvert.ToString(articleNumber.Rows[0]["RE_Product_Type"]);
                }
                if (String.Equals(Type, "PO Receive") && String.Equals(Subtype, "Received"))
                {
                    if (TypeConvert.ToBoolean(serialized) && Convert.IsDBNull(productSerialNumberId))
                    {
                        //DataTable storageLocationId = this.DefaultDataAccess.GetDataTable("RE_Inventory for InventoryId?",new object[]{inventoryId},new string[]{"Storage_Location_Id"});
                        bool voucher = String.Equals(prodType,"Voucher")?true:false;
                        newSerialNumber = createSerialNumber(serialNumber,productId,artNumber,true,StorageLocation,voucher,"In Stock");
                        //return newSerialNumber;
                    }
                }

                if (TypeConvert.ToBoolean(serialized) && !Convert.IsDBNull(productSerialNumberId))
                {
                    bool voucher = String.Equals(prodType, "Voucher") ? true : false;
                    if (voucher)
                    {
                        voucherExpiryMonths = TypeConvert.ToInt32(this.DefaultDataAccess.SqlIndex("RE_Line_Of_Business", "Voucher_Expiry_In_Months", Id.Create(lobID)));
                        voucherExpiryDate = DateTime.Now.AddMonths(voucherExpiryMonths);
                    }
                        
                    //if (String.Equals(Type, "Sale") && String.Equals(Subtype, "Sale"))
                    //{
                    //    voucherStatus = "Sold";
                    //}
                    updateSerialNumber(serialNumber, productId, artNumber, availableForSale, storageLocation, voucher, voucherStatus, voucherExpiryDate);
                }

                using (DataTable newInventoryMovement = this.DefaultDataAccess.GetNewDataTable("RE_Inventory_Movement", new string[] { "Inventory_Id", "Product_Id", 
                "SKU","Storage_Location_Id","Storage_Location_Code","Quantity","Direction","Reason","Movement_Date","Ref_Order_Id","Ref_Inventory_Trnsfr_Id",
                "Product_Serial_No_Id","Inv_Trnsf_Rec_Batch_Id"}))
                {
                    DataRow newInventoryMovementRow = newInventoryMovement.NewRow();

                    newInventoryMovementRow["Inventory_Id"] = inventoryId;
                    newInventoryMovementRow["Product_Id"] = productId;
                    newInventoryMovementRow["SKU"] = SKU;
                    newInventoryMovementRow["Storage_Location_Id"] = StorageLocation;
                    newInventoryMovementRow["Storage_Location_Code"] = storageLocationCode;
                    newInventoryMovementRow["Quantity"] = quantity;
                    newInventoryMovementRow["Direction"] = direction;
                    newInventoryMovementRow["Reason"] = reason;
                    newInventoryMovementRow["Movement_Date"] = DateTime.Now;
                    newInventoryMovementRow["Ref_Order_Id"] = refOrderId;
                    newInventoryMovementRow["Ref_Inventory_Trnsfr_Id"] = refInvTransferId;//TypeConvert.ToDBValue(Id.Create(refInvTransferId));
                    if (Convert.IsDBNull(productSerialNumberId))
                    {
                        newInventoryMovementRow["Product_Serial_No_Id"] = newSerialNumber;
                    }
                    else
                    {
                        newInventoryMovementRow["Product_Serial_No_Id"] = productSerialNumberId;
                    }


                    newInventoryMovementRow["Inv_Trnsf_Rec_Batch_Id"] = invTransferRecBatchId;
                    
                    newInventoryMovement.Rows.Add(newInventoryMovementRow);

                    this.DefaultDataAccess.SaveDataTable(newInventoryMovement);
                }

                updateInventory(inventoryId,direction,quantity);
            }
            catch (Exception ex)
            {
                //if (!System.Diagnostics.EventLog.SourceExists("Pivotal Connection Error"))
                //    System.Diagnostics.EventLog.CreateEventSource("Pivotal Connection Error","Pivotal");

                ////System.Diagnostics.EventLog.WriteEntry(;
                //System.Diagnostics.EventLog.WriteEntry("Pivotal Connection Error", "OLEDB Connection Error test",
                //    System.Diagnostics.EventLogEntryType.Warning,999);
                throw new PivotalApplicationCoreException(ex.Message, ex);
            }
        }

        //<summary>
        // Process Inventory based on Sale Type and SubType
        // </summary>
        // <param name="Type">Saale Type</param>
        // <param name="Subtype">Sale SubType</param>
        // <param name="orderId">Order Id</param>

        [TaskExecute]
        public virtual void processInventory(string Type,string Subtype,object orderId)
        {
            try
            {
                DataTable inventory=null;
                DataTable orderProduct=null;
                DataTable invTransferProduct=null;
                DataTable invTransferRecBatch = null;
                DataTable invTransfer = null;
                //DataTable storageLocationSales = null;
                //DataTable storageLocationTradeIn = null;
                //DataTable storageLocationRMA = null;
                DataTable storageLocationTransit = null;

                object storeID = this.DefaultDataAccess.SqlIndex("Employee", "RE_Store_Id", this.SystemServer.UserProfile.EmployeeId);
                object serialNumberId = DBNull.Value;
                string serialNumber = string.Empty;
                int quantity;
                string direction = string.Empty;
                string reason = string.Empty;
                bool serialized = false;
                string articleNumber = string.Empty;
                string storageLocationCode = string.Empty;

                if (String.Equals(Type, "Sale") || String.Equals(Type, "Void"))
                {
                    orderProduct = this.DefaultDataAccess.GetDataTable("RE_Order Products with Inventorized and InventoryUpdateStatus as Processed with Order?"
                        , new object[] { orderId }, new string[] { "Product_Id", "RE_Product_Serial_No_Id", "Quantity" });
                }

                if (String.Equals(Type, "RMA") || String.Equals(Type, "Inventory Transfer"))
                {
                    invTransferProduct = this.DefaultDataAccess.GetDataTable("RE Inv Transfer Product for InvTransfer Id?"
                        , new object[] { orderId }, new string[] { });
                }

                if (String.Equals(Type, "Inventory Transfer") || String.Equals(Type, "PO Receive")|| String.Equals(Type,"Inventory Receive"))
                {
                    invTransfer = this.DefaultDataAccess.GetDataTable("RE_Inventory Transfer for Inventory Transfer Id?", new object[] { orderId },
                            new string[] { "Receive_Batch_ID", "To_Storage_Location_Id", "From_Storage_Location_Id" });
                    if (invTransfer != null && invTransfer.Rows.Count > 0)
                    {
                        invTransferRecBatch = this.DefaultDataAccess.GetDataTable("RE Inv Transfer Rec Batch for InvTransfer Id and Recieve Batch?"
                            , new object[] { orderId, invTransfer.Rows[0]["Receive_Batch_ID"] }, new string[] { });
                    }
                }

                //DS: 21052013 - Performance Improvement.
                //"RE Storage Location with Store Id ?"
                DataTable storageLocation = this.DefaultDataAccess.GetDataTable("RE Storage Location with Store Id ?", new object[] { storeID }, new string[] { "RE_Storage_Location_Id", "Type", "Code_" });
                object storageLocationIdSales = (storageLocation.AsEnumerable().Where(a => string.Equals(TypeConvert.ToString(a["Type"]), "Sales")).ToArray())[0]["RE_Storage_Location_Id"];
                object storageLocationIdTradeIn = (storageLocation.AsEnumerable().Where(a => string.Equals(TypeConvert.ToString(a["Type"]), "Trade-In")).ToArray())[0]["RE_Storage_Location_Id"];
                object storageLocationIdRMA = (storageLocation.AsEnumerable().Where(a => string.Equals(TypeConvert.ToString(a["Type"]), "RMA")).ToArray())[0]["RE_Storage_Location_Id"];

                //storageLocationSales = this.DefaultDataAccess.GetDataTable("RE Storage Location with Store Id and Type as Sales?", new object[] {storeID},new string[] { });
                //storageLocationTradeIn = this.DefaultDataAccess.GetDataTable("RE Storage Location with Store Id and Type as Trade-In?", new object[] { storeID }, new string[] { });
                //storageLocationRMA = this.DefaultDataAccess.GetDataTable("RE Storage Location with Store Id and Type as RMA?", new object[] { storeID }, new string[] { }); ;
                storageLocationTransit = this.DefaultDataAccess.GetDataTable("RE Storage Location for Type as Transit?", new object[] { }, new string[] { });

                #region Type:Sale SubType=Sale
                if (String.Equals(Type, "Sale") && String.Equals(Subtype, "Sale"))
                {
                    if (orderProduct != null && orderProduct.Rows.Count > 0)
                    {
                        foreach (DataRow drTemp in orderProduct.Rows)
                        {
                            inventory = this.DefaultDataAccess.GetDataTable("RE_Inventory for StorageLocation? Product?", new object[] { storageLocationIdSales,
                            drTemp["Product_Id"]}, new string[] { });

                            if (inventory != null && inventory.Rows.Count > 0)
                            {
                                DataTable product = this.DefaultDataAccess.GetDataTable("SFA: Products id equal to ?", new object[] { drTemp["Product_Id"] }, "RE_Serialized", "RE_Article_Number");

                                serialized = TypeConvert.ToBoolean(product.Rows[0]["RE_Serialized"]);
                                articleNumber = TypeConvert.ToString(product.Rows[0]["RE_Article_Number"]);
                                storageLocationCode = TypeConvert.ToString((storageLocation.AsEnumerable().Where(a => string.Equals(TypeConvert.ToString(a["Type"]), "Sales")).ToArray())[0]["Code_"]);

                                serialNumberId = serialized ? drTemp["RE_Product_Serial_No_Id"] : DBNull.Value;
                                serialNumber = serialized ? TypeConvert.ToString(this.DefaultDataAccess.SqlIndex("RE_Product_Serial_No", "Serial_Number", Id.Create(drTemp["RE_Product_Serial_No_Id"]))) : String.Empty;

                                CreateInventoryMovement(Type, Subtype, inventory.Rows[0]["RE_Inventory_Id"], drTemp["Product_Id"], serialized,
                                    articleNumber, storageLocationIdSales, storageLocationCode,
                                    TypeConvert.ToInt32(drTemp["Quantity"]), "Subtract", "Sale", orderId, DBNull.Value, serialNumberId, serialNumber, DBNull.Value);
                            }
                        }
                    }
                }
                #endregion

                #region Type:Sale SubType=Exchange
                if (String.Equals(Type, "Sale") && String.Equals(Subtype, "Exchange"))
                {
                    if (orderProduct != null && orderProduct.Rows.Count > 0)
                    {
                        foreach (DataRow drTemp in orderProduct.Rows)
                        {
                            inventory = this.DefaultDataAccess.GetDataTable("RE_Inventory for StorageLocation? Product?", new object[] { storageLocationIdSales,
                            drTemp["Product_Id"]}, new string[] { });

                            if (inventory != null && inventory.Rows.Count > 0)
                            {
                                DataTable product = this.DefaultDataAccess.GetDataTable("SFA: Products id equal to ?", new object[] { drTemp["Product_Id"] }, "RE_Serialized", "RE_Article_Number");

                                serialized = TypeConvert.ToBoolean(product.Rows[0]["RE_Serialized"]);
                                articleNumber = TypeConvert.ToString(product.Rows[0]["RE_Article_Number"]);
                                storageLocationCode = TypeConvert.ToString((storageLocation.AsEnumerable().Where(a => string.Equals(TypeConvert.ToString(a["Type"]), "Sales")).ToArray())[0]["Code_"]);

                                serialNumberId = TypeConvert.ToBoolean(serialized) ? drTemp["RE_Product_Serial_No_Id"] : DBNull.Value;
                                serialNumber = serialized ? TypeConvert.ToString(this.DefaultDataAccess.SqlIndex("RE_Product_Serial_No", "Serial_Number", Id.Create(drTemp["RE_Product_Serial_No_Id"]))) : String.Empty;
                                if (TypeConvert.ToInt32(drTemp["Quantity"]) < 0)
                                {
                                    quantity = Math.Abs(TypeConvert.ToInt32(drTemp["Quantity"]));
                                    direction = "Add";
                                    reason = "Exchange";
                                }
                                else
                                {
                                    quantity = TypeConvert.ToInt32(drTemp["Quantity"]);
                                    direction = "Subtract";
                                    reason = "Sale";
                                }

                                CreateInventoryMovement(Type, Subtype, inventory.Rows[0]["RE_Inventory_Id"], drTemp["Product_Id"], serialized,
                                   articleNumber, storageLocationIdSales, storageLocationCode,
                                    quantity, direction, reason, orderId, DBNull.Value, serialNumberId, serialNumber, DBNull.Value);
                            }
                        }
                    }
                }
                #endregion

                #region Type:Sale SubType=Refund
                if (String.Equals(Type, "Sale") && String.Equals(Subtype, "Refund"))
                {
                    if (orderProduct != null && orderProduct.Rows.Count > 0)
                    {
                        foreach (DataRow drTemp in orderProduct.Rows)
                        {
                            inventory = this.DefaultDataAccess.GetDataTable("RE_Inventory for StorageLocation? Product?", new object[] { storageLocationIdSales,
                            drTemp["Product_Id"]}, new string[] { });

                            if (inventory != null && inventory.Rows.Count > 0)
                            {
                                DataTable product = this.DefaultDataAccess.GetDataTable("SFA: Products id equal to ?", new object[] { drTemp["Product_Id"] }, "RE_Serialized", "RE_Article_Number");

                                serialized = TypeConvert.ToBoolean(product.Rows[0]["RE_Serialized"]);
                                articleNumber = TypeConvert.ToString(product.Rows[0]["RE_Article_Number"]);
                                storageLocationCode = TypeConvert.ToString((storageLocation.AsEnumerable().Where(a => string.Equals(TypeConvert.ToString(a["Type"]), "Sales")).ToArray())[0]["Code_"]);

                                serialNumberId = TypeConvert.ToBoolean(serialized) ? drTemp["RE_Product_Serial_No_Id"] : DBNull.Value;
                                serialNumber = serialized ? TypeConvert.ToString(this.DefaultDataAccess.SqlIndex("RE_Product_Serial_No", "Serial_Number", Id.Create(drTemp["RE_Product_Serial_No_Id"]))) : String.Empty; 
                                CreateInventoryMovement(Type, Subtype, inventory.Rows[0]["RE_Inventory_Id"], drTemp["Product_Id"], serialized,
                                   articleNumber, storageLocationIdSales, storageLocationCode,
                                    Math.Abs(TypeConvert.ToInt32(drTemp["Quantity"])), "Add", "Refund", orderId, DBNull.Value, serialNumberId, serialNumber, DBNull.Value);
                            }
                        }
                    }
                }
                #endregion

                #region Type:Sale SubType=Trade-In
                if (String.Equals(Type, "Sale") && String.Equals(Subtype, "Trade-In"))
                {
                    if (orderProduct != null && orderProduct.Rows.Count > 0)
                    {
                        foreach (DataRow drTemp in orderProduct.Rows)
                        {
                            DataTable product = this.DefaultDataAccess.GetDataTable("SFA: Products id equal to ?", new object[] { drTemp["Product_Id"] }, "RE_Serialized", "RE_Article_Number", "RE_Product_Type");
                            string productType = TypeConvert.ToString(product.Rows[0]["RE_Product_Type"]);
                            if (String.Equals(productType, "Trade-In"))
                            {
                                inventory = this.DefaultDataAccess.GetDataTable("RE_Inventory for StorageLocation? Product?", new object[] { storageLocationIdTradeIn, drTemp["Product_Id"]}, new string[] { });
                            }
                            else
                            {
                                inventory = this.DefaultDataAccess.GetDataTable("RE_Inventory for StorageLocation? Product?", new object[] { storageLocationIdSales, drTemp["Product_Id"]}, new string[] { });
                            }
                            if (inventory != null && inventory.Rows.Count > 0)
                            {
                                serialized = TypeConvert.ToBoolean(product.Rows[0]["RE_Serialized"]);
                                articleNumber = TypeConvert.ToString(product.Rows[0]["RE_Article_Number"]);
                                storageLocationCode = TypeConvert.ToString((storageLocation.AsEnumerable().Where(a => string.Equals(TypeConvert.ToString(a["Type"]), "Sales")).ToArray())[0]["Code_"]);

                                serialNumberId = TypeConvert.ToBoolean(serialized) ? drTemp["RE_Product_Serial_No_Id"] : DBNull.Value;
                                serialNumber = serialized ? TypeConvert.ToString(this.DefaultDataAccess.SqlIndex("RE_Product_Serial_No", "Serial_Number", Id.Create(drTemp["RE_Product_Serial_No_Id"]))) : String.Empty;

                                if (String.Equals(productType, "Trade-In"))
                                {
                                    quantity = Math.Abs(TypeConvert.ToInt32(drTemp["Quantity"]));
                                    direction = "Add";
                                    reason = "Trade-In";
                                }
                                else
                                {
                                    quantity = TypeConvert.ToInt32(drTemp["Quantity"]);
                                    direction = "Subtract";
                                    reason = "Sale";
                                }
                                if (String.Equals(productType, "Trade-In"))
                                {
                                    CreateInventoryMovement(Type, Subtype, inventory.Rows[0]["RE_Inventory_Id"], drTemp["Product_Id"], serialized,
                                        articleNumber, storageLocationIdTradeIn, storageLocationCode,
                                        quantity, direction, reason, orderId, DBNull.Value, serialNumberId, serialNumber, DBNull.Value);
                                }
                                else
                                {
                                    CreateInventoryMovement(Type, Subtype, inventory.Rows[0]["RE_Inventory_Id"], drTemp["Product_Id"], serialized,
                                        articleNumber, storageLocationIdSales, storageLocationCode,
                                        quantity, direction, reason, orderId, DBNull.Value, serialNumberId, serialNumber, DBNull.Value);
                                }
                            }
                        }
                    }
                }
                #endregion

                #region Type:Void
                if (String.Equals(Type, "Void"))
                {
                    if (orderProduct != null && orderProduct.Rows.Count > 0)
                    {
                        foreach (DataRow drTemp in orderProduct.Rows)
                        {
                            inventory = this.DefaultDataAccess.GetDataTable("RE_Inventory for StorageLocation? Product?", new object[] { storageLocationIdSales,
                            drTemp["Product_Id"]}, new string[] { });

                            if (inventory != null && inventory.Rows.Count > 0)
                            {
                                DataTable product = this.DefaultDataAccess.GetDataTable("SFA: Products id equal to ?", new object[] { drTemp["Product_Id"] }, "RE_Serialized", "RE_Article_Number");

                                serialized = TypeConvert.ToBoolean(product.Rows[0]["RE_Serialized"]);
                                articleNumber = TypeConvert.ToString(product.Rows[0]["RE_Article_Number"]);
                                storageLocationCode = TypeConvert.ToString((storageLocation.AsEnumerable().Where(a => string.Equals(TypeConvert.ToString(a["Type"]), "Sales")).ToArray())[0]["Code_"]);

                                serialNumberId = TypeConvert.ToBoolean(serialized) ? drTemp["RE_Product_Serial_No_Id"] : DBNull.Value;
                                serialNumber = serialized ? TypeConvert.ToString(this.DefaultDataAccess.SqlIndex("RE_Product_Serial_No", "Serial_Number", Id.Create(drTemp["RE_Product_Serial_No_Id"]))) : String.Empty; 

                                if (TypeConvert.ToInt32(drTemp["Quantity"]) < 0)
                                {
                                    quantity = Math.Abs(TypeConvert.ToInt32(drTemp["Quantity"]));
                                    direction = "Subtract";
                                    reason = "Void";
                                }
                                else
                                {
                                    quantity = TypeConvert.ToInt32(drTemp["Quantity"]);
                                    direction = "Add";
                                    reason = "Void";
                                }

                                CreateInventoryMovement(Type, Subtype, inventory.Rows[0]["RE_Inventory_Id"], drTemp["Product_Id"], serialized, articleNumber, storageLocationIdSales, storageLocationCode,
                                    quantity, direction, reason, orderId, DBNull.Value, serialNumberId, serialNumber, DBNull.Value);
                            }
                        }
                    }
                }
                #endregion

                #region Type:RMA SubType=Issue
                if (String.Equals(Type, "RMA") && String.Equals(Subtype, "Issue"))
                {
                    if (invTransferProduct != null && invTransferProduct.Rows.Count > 0)
                    {
                        foreach (DataRow drTemp in invTransferProduct.Rows)
                        {
                            inventory = this.DefaultDataAccess.GetDataTable("RE_Inventory for StorageLocation? Product?", new object[] { storageLocationIdSales,
                            drTemp["Product_Id"]}, new string[] { });

                            if (inventory != null && inventory.Rows.Count > 0)
                            {
                                DataTable product = this.DefaultDataAccess.GetDataTable("SFA: Products id equal to ?", new object[] { drTemp["Product_Id"] }, "RE_Serialized", "RE_Article_Number");

                                serialized = TypeConvert.ToBoolean(product.Rows[0]["RE_Serialized"]);
                                articleNumber = TypeConvert.ToString(product.Rows[0]["RE_Article_Number"]);
                                storageLocationCode = TypeConvert.ToString((storageLocation.AsEnumerable().Where(a => string.Equals(TypeConvert.ToString(a["Type"]), "Sales")).ToArray())[0]["Code_"]);

                                serialNumberId = TypeConvert.ToBoolean(serialized) ? drTemp["RE_Product_Serial_No_Id"] : DBNull.Value;
                                serialNumber = serialized ? TypeConvert.ToString(this.DefaultDataAccess.SqlIndex("RE_Product_Serial_No", "Serial_Number", Id.Create(drTemp["RE_Product_Serial_No_Id"]))) : String.Empty; 

                                CreateInventoryMovement(Type, Subtype, inventory.Rows[0]["RE_Inventory_Id"], drTemp["Product_Id"], serialized, articleNumber, storageLocationIdSales, storageLocationCode,
                                    TypeConvert.ToInt32(drTemp["Quantity_Issued"]), "Subtract", "RMA", DBNull.Value, orderId, serialNumberId, serialNumber, DBNull.Value);
                            }
                        }
                    }

                    if (invTransferProduct != null && invTransferProduct.Rows.Count > 0)
                    {
                        foreach (DataRow drTemp in invTransferProduct.Rows)
                        {
                            inventory = this.DefaultDataAccess.GetDataTable("RE_Inventory for StorageLocation? Product?", new object[] { storageLocationIdRMA,
                            drTemp["Product_Id"]}, new string[] { });

                            if (inventory != null && inventory.Rows.Count > 0)
                            {
                                DataTable product = this.DefaultDataAccess.GetDataTable("SFA: Products id equal to ?", new object[] { drTemp["Product_Id"] }, "RE_Serialized", "RE_Article_Number");

                                serialized = TypeConvert.ToBoolean(product.Rows[0]["RE_Serialized"]);
                                articleNumber = TypeConvert.ToString(product.Rows[0]["RE_Article_Number"]);
                                storageLocationCode = TypeConvert.ToString((storageLocation.AsEnumerable().Where(a => string.Equals(TypeConvert.ToString(a["Type"]), "RMA")).ToArray())[0]["Code_"]);

                                serialNumberId = TypeConvert.ToBoolean(serialized) ? drTemp["RE_Product_Serial_No_Id"] : DBNull.Value;
                                serialNumber = serialized ? TypeConvert.ToString(this.DefaultDataAccess.SqlIndex("RE_Product_Serial_No", "Serial_Number", Id.Create(drTemp["RE_Product_Serial_No_Id"]))) : String.Empty; 

                                CreateInventoryMovement(Type, Subtype, inventory.Rows[0]["RE_Inventory_Id"], drTemp["Product_Id"], serialized, articleNumber, storageLocationIdRMA, storageLocationCode,
                                    TypeConvert.ToInt32(drTemp["Quantity_Issued"]), "Add", "RMA", DBNull.Value, orderId, serialNumberId, serialNumber, DBNull.Value);
                            }
                        }
                    }
                }
                #endregion

                #region Type:RMA SubType=Collect
                if (String.Equals(Type, "RMA") && String.Equals(Subtype, "Collected"))
                {
                    if (invTransferProduct != null && invTransferProduct.Rows.Count > 0)
                    {
                        foreach (DataRow drTemp in invTransferProduct.Rows)
                        {
                            inventory = this.DefaultDataAccess.GetDataTable("RE_Inventory for StorageLocation? Product?", new object[] { storageLocationIdRMA,
                            drTemp["Product_Id"]}, new string[] { });

                            if (inventory != null && inventory.Rows.Count > 0)
                            {
                                DataTable product = this.DefaultDataAccess.GetDataTable("SFA: Products id equal to ?", new object[] { drTemp["Product_Id"] }, "RE_Serialized", "RE_Article_Number");

                                serialized = TypeConvert.ToBoolean(product.Rows[0]["RE_Serialized"]);
                                articleNumber = TypeConvert.ToString(product.Rows[0]["RE_Article_Number"]);
                                storageLocationCode = TypeConvert.ToString((storageLocation.AsEnumerable().Where(a => string.Equals(TypeConvert.ToString(a["Type"]), "RMA")).ToArray())[0]["Code_"]);

                                serialNumberId = TypeConvert.ToBoolean(serialized) ? drTemp["RE_Product_Serial_No_Id"] : DBNull.Value;
                                serialNumber = serialized ? TypeConvert.ToString(this.DefaultDataAccess.SqlIndex("RE_Product_Serial_No", "Serial_Number", Id.Create(drTemp["RE_Product_Serial_No_Id"]))) : String.Empty; 

                                CreateInventoryMovement(Type, Subtype, inventory.Rows[0]["RE_Inventory_Id"], drTemp["Product_Id"], serialized, articleNumber, storageLocationIdRMA, storageLocationCode,
                                    TypeConvert.ToInt32(drTemp["Quantity_Issued"]), "Subtract", "RMA", DBNull.Value, orderId, serialNumberId, serialNumber, DBNull.Value);
                            }
                        }
                    }
                }
                #endregion

                #region Type:RMA SubType=Cancel
                if (String.Equals(Type, "RMA") && String.Equals(Subtype, "Cancelled"))
                {
                    if (invTransferProduct != null && invTransferProduct.Rows.Count > 0)
                    {
                        foreach (DataRow drTemp in invTransferProduct.Rows)
                        {
                            inventory = this.DefaultDataAccess.GetDataTable("RE_Inventory for StorageLocation? Product?", new object[] { storageLocationIdRMA,
                            drTemp["Product_Id"]}, new string[] { });

                            if (inventory != null && inventory.Rows.Count > 0)
                            {
                                DataTable product = this.DefaultDataAccess.GetDataTable("SFA: Products id equal to ?", new object[] { drTemp["Product_Id"] }, "RE_Serialized", "RE_Article_Number");

                                serialized = TypeConvert.ToBoolean(product.Rows[0]["RE_Serialized"]);
                                articleNumber = TypeConvert.ToString(product.Rows[0]["RE_Article_Number"]);
                                storageLocationCode = TypeConvert.ToString((storageLocation.AsEnumerable().Where(a => string.Equals(TypeConvert.ToString(a["Type"]), "RMA")).ToArray())[0]["Code_"]);

                                serialNumberId = TypeConvert.ToBoolean(serialized) ? drTemp["RE_Product_Serial_No_Id"] : DBNull.Value;
                                serialNumber = serialized ? TypeConvert.ToString(this.DefaultDataAccess.SqlIndex("RE_Product_Serial_No", "Serial_Number", Id.Create(drTemp["RE_Product_Serial_No_Id"]))) : String.Empty; 

                                CreateInventoryMovement(Type, Subtype, inventory.Rows[0]["RE_Inventory_Id"], drTemp["Product_Id"], serialized, articleNumber, storageLocationIdRMA, storageLocationCode,
                                    TypeConvert.ToInt32(drTemp["Quantity_Issued"]), "Subtract", "RMA", DBNull.Value, orderId, serialNumberId, serialNumber, DBNull.Value);
                            }
                        }
                    }

                    if (invTransferProduct != null && invTransferProduct.Rows.Count > 0)
                    {
                        foreach (DataRow drTemp in invTransferProduct.Rows)
                        {
                            inventory = this.DefaultDataAccess.GetDataTable("RE_Inventory for StorageLocation? Product?", new object[] { storageLocationIdSales,
                            drTemp["Product_Id"]}, new string[] { });

                            if (inventory != null && inventory.Rows.Count > 0)
                            {
                                DataTable product = this.DefaultDataAccess.GetDataTable("SFA: Products id equal to ?", new object[] { drTemp["Product_Id"] }, "RE_Serialized", "RE_Article_Number");

                                serialized = TypeConvert.ToBoolean(product.Rows[0]["RE_Serialized"]);
                                articleNumber = TypeConvert.ToString(product.Rows[0]["RE_Article_Number"]);
                                storageLocationCode = TypeConvert.ToString((storageLocation.AsEnumerable().Where(a => string.Equals(TypeConvert.ToString(a["Type"]), "Sales")).ToArray())[0]["Code_"]);

                                serialNumberId = TypeConvert.ToBoolean(serialized) ? drTemp["RE_Product_Serial_No_Id"] : DBNull.Value;
                                serialNumber = serialized ? TypeConvert.ToString(this.DefaultDataAccess.SqlIndex("RE_Product_Serial_No", "Serial_Number", Id.Create(drTemp["RE_Product_Serial_No_Id"]))) : String.Empty;

                                CreateInventoryMovement(Type, Subtype, inventory.Rows[0]["RE_Inventory_Id"], drTemp["Product_Id"], serialized, articleNumber, storageLocationIdSales,storageLocationCode,
                                    TypeConvert.ToInt32(drTemp["Quantity_Issued"]), "Add", "RMA", DBNull.Value, orderId, serialNumberId, serialNumber, DBNull.Value);
                            }
                        }
                    }
                }  
                #endregion

                #region Type:Inventory Transfer SubType=Issue
                if (String.Equals(Type, "Inventory Transfer") && String.Equals(Subtype, "Issued"))
                {
                    if (invTransferProduct != null && invTransferProduct.Rows.Count > 0)
                    {
                        foreach (DataRow drTemp in invTransferProduct.Rows)
                        {
                            if (invTransfer != null && invTransfer.Rows.Count > 0)
                            {
                                inventory = this.DefaultDataAccess.GetDataTable("RE_Inventory for StorageLocation? Product?", new object[] {invTransfer.Rows[0]["From_Storage_Location_Id"],
                                drTemp["Product_Id"]}, new string[] { });

                                if (inventory != null && inventory.Rows.Count > 0)
                                {
                                    DataTable product = this.DefaultDataAccess.GetDataTable("SFA: Products id equal to ?", new object[] { drTemp["Product_Id"] }, "RE_Serialized", "RE_Article_Number");

                                    serialized = TypeConvert.ToBoolean(product.Rows[0]["RE_Serialized"]);
                                    articleNumber = TypeConvert.ToString(product.Rows[0]["RE_Article_Number"]);
                                    storageLocationCode = TypeConvert.ToString(this.DefaultDataAccess.SqlIndex("RE_Storage_Location", "Code_", Id.Create(invTransfer.Rows[0]["From_Storage_Location_Id"])));

                                    serialNumberId = TypeConvert.ToBoolean(serialized) ? drTemp["RE_Product_Serial_No_Id"] : DBNull.Value;
                                    serialNumber = serialized ? TypeConvert.ToString(this.DefaultDataAccess.SqlIndex("RE_Product_Serial_No", "Serial_Number", Id.Create(drTemp["RE_Product_Serial_No_Id"]))) : String.Empty; 

                                    CreateInventoryMovement(Type, Subtype, inventory.Rows[0]["RE_Inventory_Id"], drTemp["Product_Id"], serialized, articleNumber, invTransfer.Rows[0]["From_Storage_Location_Id"], storageLocationCode,
                                        TypeConvert.ToInt32(drTemp["Quantity_Issued"]), "Subtract", "Inventory Transfer", DBNull.Value, orderId, serialNumberId, serialNumber, DBNull.Value);
                                }
                            }
                        }
                    }

                    if (invTransferProduct != null && invTransferProduct.Rows.Count > 0)
                    {
                        foreach (DataRow drTemp in invTransferProduct.Rows)
                        {
                            inventory = this.DefaultDataAccess.GetDataTable("RE_Inventory for StorageLocation? Product?", new object[] { storageLocationTransit.Rows[0]["RE_Storage_Location_Id"],
                            drTemp["Product_Id"]}, new string[] { });

                            if (inventory != null && inventory.Rows.Count > 0)
                            {
                                DataTable product = this.DefaultDataAccess.GetDataTable("SFA: Products id equal to ?", new object[] { drTemp["Product_Id"] }, "RE_Serialized", "RE_Article_Number");

                                serialized = TypeConvert.ToBoolean(product.Rows[0]["RE_Serialized"]);
                                articleNumber = TypeConvert.ToString(product.Rows[0]["RE_Article_Number"]);
                                storageLocationCode = TypeConvert.ToString(this.DefaultDataAccess.SqlIndex("RE_Storage_Location", "Code_", Id.Create(storageLocationTransit.Rows[0]["RE_Storage_Location_Id"])));

                                serialNumberId = TypeConvert.ToBoolean(serialized) ? drTemp["RE_Product_Serial_No_Id"] : DBNull.Value;
                                serialNumber = serialized ? TypeConvert.ToString(this.DefaultDataAccess.SqlIndex("RE_Product_Serial_No", "Serial_Number", Id.Create(drTemp["RE_Product_Serial_No_Id"]))) : String.Empty; 

                                CreateInventoryMovement(Type, Subtype, inventory.Rows[0]["RE_Inventory_Id"], drTemp["Product_Id"], serialized, articleNumber, storageLocationTransit.Rows[0]["RE_Storage_Location_Id"], storageLocationCode,
                                    TypeConvert.ToInt32(drTemp["Quantity_Issued"]), "Add", "Inventory Transfer", DBNull.Value, orderId, serialNumberId, serialNumber, DBNull.Value);
                            }
                        }
                    }
                }
                #endregion

                #region Type:Inventory Transfer SubType=Receive
                if (String.Equals(Type, "Inventory Transfer") && String.Equals(Subtype, "Received"))
                {
                    if (invTransferRecBatch != null && invTransferRecBatch.Rows.Count > 0)
                    {
                        int index = 0;
                        foreach (DataRow drTemp in invTransferRecBatch.Rows)
                        {
                            inventory = this.DefaultDataAccess.GetDataTable("RE_Inventory for StorageLocation? Product?", new object[] { storageLocationTransit.Rows[0]["RE_Storage_Location_Id"],
                            drTemp["Product_Id"]}, new string[] { });

                            if (inventory != null && inventory.Rows.Count > 0)
                            {
                                DataTable product = this.DefaultDataAccess.GetDataTable("SFA: Products id equal to ?", new object[] { drTemp["Product_Id"] }, "RE_Serialized", "RE_Article_Number");

                                serialized = TypeConvert.ToBoolean(product.Rows[0]["RE_Serialized"]);
                                articleNumber = TypeConvert.ToString(product.Rows[0]["RE_Article_Number"]);
                                storageLocationCode = TypeConvert.ToString(this.DefaultDataAccess.SqlIndex("RE_Storage_Location", "Code_", Id.Create(storageLocationTransit.Rows[0]["RE_Storage_Location_Id"])));

                                serialNumberId = TypeConvert.ToBoolean(serialized) ? drTemp["Product_Serial_No_Id"] : DBNull.Value;
                                serialNumber = serialized ? TypeConvert.ToString(this.DefaultDataAccess.SqlIndex("RE_Product_Serial_No", "Serial_Number", Id.Create(drTemp["Product_Serial_No_Id"]))) : String.Empty; 

                                DataTable invTransRecBatch = this.DefaultDataAccess.GetDataTable("RE Inv Transfer Rec Batch for InvTransfer Id and Recieve Batch?",
                                       new object[] { orderId, invTransfer.Rows[0]["Receive_Batch_ID"] }, new string[] { "RE_Inv_Trnsf_Rec_Batch_Id" });
                                if (invTransRecBatch != null && invTransRecBatch.Rows.Count > 0)
                                {
                                    CreateInventoryMovement(Type, Subtype, inventory.Rows[0]["RE_Inventory_Id"], drTemp["Product_Id"], serialized,
                                        articleNumber, storageLocationTransit.Rows[0]["RE_Storage_Location_Id"], storageLocationCode,
                                        TypeConvert.ToInt32(drTemp["Qty"]), "Subtract", "Inventory Transfer", DBNull.Value, orderId, serialNumberId, serialNumber, invTransRecBatch.Rows[index]["RE_Inv_Trnsf_Rec_Batch_Id"]);
                                    index += 1;
                                }
                            }
                        }
                    }
                    if (invTransferRecBatch != null && invTransferRecBatch.Rows.Count > 0)
                    {
                        int index = 0;
                        foreach (DataRow drTemp in invTransferRecBatch.Rows)
                        {
                            if (invTransfer != null && invTransfer.Rows.Count > 0)
                            {   
                                inventory = this.DefaultDataAccess.GetDataTable("RE_Inventory for StorageLocation? Product?", new object[] {invTransfer.Rows[0]["To_Storage_Location_Id"],
                                drTemp["Product_Id"]}, new string[] { });
                                if (inventory != null && inventory.Rows.Count > 0)
                                {
                                    DataTable product = this.DefaultDataAccess.GetDataTable("SFA: Products id equal to ?", new object[] { drTemp["Product_Id"] }, "RE_Serialized", "RE_Article_Number");

                                    serialized = TypeConvert.ToBoolean(product.Rows[0]["RE_Serialized"]);
                                    articleNumber = TypeConvert.ToString(product.Rows[0]["RE_Article_Number"]);
                                    storageLocationCode = TypeConvert.ToString(this.DefaultDataAccess.SqlIndex("RE_Storage_Location", "Code_", Id.Create(invTransfer.Rows[0]["To_Storage_Location_Id"])));

                                    serialNumberId = TypeConvert.ToBoolean(serialized) ? drTemp["Product_Serial_No_Id"] : DBNull.Value;
                                    serialNumber = serialized ? TypeConvert.ToString(this.DefaultDataAccess.SqlIndex("RE_Product_Serial_No", "Serial_Number", Id.Create(drTemp["Product_Serial_No_Id"]))) : String.Empty;

                                    DataTable invTransRecBatch = this.DefaultDataAccess.GetDataTable("RE Inv Transfer Rec Batch for InvTransfer Id and Recieve Batch?",
                                        new object[] { orderId, invTransfer.Rows[0]["Receive_Batch_ID"] }, new string[] { "RE_Inv_Trnsf_Rec_Batch_Id" });
                                    if (invTransRecBatch != null && invTransRecBatch.Rows.Count > 0)
                                    {
                                        CreateInventoryMovement(Type, Subtype, inventory.Rows[0]["RE_Inventory_Id"], drTemp["Product_Id"], serialized,
                                            articleNumber, invTransfer.Rows[0]["To_Storage_Location_Id"], storageLocationCode,
                                            TypeConvert.ToInt32(drTemp["Qty"]), "Add", "Inventory Transfer", DBNull.Value, orderId, serialNumberId, serialNumber, invTransRecBatch.Rows[index]["RE_Inv_Trnsf_Rec_Batch_Id"]);
                                        index += 1;
                                    }
                                }
                            }
                        }
                    }
                }
                #endregion

                #region Type:Inventory Transfer SubType=Cancel
                if (String.Equals(Type, "Inventory Transfer") && String.Equals(Subtype, "Cancel"))
                {
                    if (invTransferProduct != null && invTransferProduct.Rows.Count > 0)
                    {
                        foreach (DataRow drTemp in invTransferProduct.Rows)
                        {
                            inventory = this.DefaultDataAccess.GetDataTable("RE_Inventory for StorageLocation? Product?", new object[] { storageLocationTransit.Rows[0]["RE_Storage_Location_Id"],
                            drTemp["Product_Id"]}, new string[] { });

                            if (inventory != null && inventory.Rows.Count > 0)
                            {
                                DataTable product = this.DefaultDataAccess.GetDataTable("SFA: Products id equal to ?", new object[] { drTemp["Product_Id"] }, "RE_Serialized", "RE_Article_Number");

                                serialized = TypeConvert.ToBoolean(product.Rows[0]["RE_Serialized"]);
                                articleNumber = TypeConvert.ToString(product.Rows[0]["RE_Article_Number"]);
                                storageLocationCode = TypeConvert.ToString(this.DefaultDataAccess.SqlIndex("RE_Storage_Location", "Code_", Id.Create(storageLocationTransit.Rows[0]["RE_Storage_Location_Id"])));

                                serialNumberId = TypeConvert.ToBoolean(serialized) ? drTemp["RE_Product_Serial_No_Id"] : DBNull.Value;
                                serialNumber = TypeConvert.ToBoolean(serialized) ? TypeConvert.ToString(drTemp["Serial_Number"]) : string.Empty;

                                CreateInventoryMovement(Type, Subtype, inventory.Rows[0]["RE_Inventory_Id"], drTemp["Product_Id"], serialized,
                                    articleNumber, storageLocationTransit.Rows[0]["RE_Storage_Location_Id"], storageLocationCode,
                                    TypeConvert.ToInt32(drTemp["Quantity"]), "Subtract", "Inventory Transfer", DBNull.Value, orderId, serialNumberId, serialNumber, DBNull.Value);
                            }
                        }
                    }
                    if (invTransferProduct != null && invTransferProduct.Rows.Count > 0)
                    {
                        foreach (DataRow drTemp in invTransferProduct.Rows)
                        {
                            if (invTransfer != null && invTransfer.Rows.Count > 0)
                            {
                                inventory = this.DefaultDataAccess.GetDataTable("RE_Inventory for StorageLocation? Product?", new object[] {invTransfer.Rows[0]["From_Storage_Location_Id"],
                                drTemp["Product_Id"]}, new string[] { });

                                if (inventory != null && inventory.Rows.Count > 0)
                                {
                                    DataTable product = this.DefaultDataAccess.GetDataTable("SFA: Products id equal to ?", new object[] { drTemp["Product_Id"] }, "RE_Serialized", "RE_Article_Number");

                                    serialized = TypeConvert.ToBoolean(product.Rows[0]["RE_Serialized"]);
                                    articleNumber = TypeConvert.ToString(product.Rows[0]["RE_Article_Number"]);
                                    storageLocationCode = TypeConvert.ToString(this.DefaultDataAccess.SqlIndex("RE_Storage_Location", "Code_", Id.Create(invTransfer.Rows[0]["From_Storage_Location_Id"])));

                                    serialNumberId = TypeConvert.ToBoolean(serialized) ? drTemp["RE_Product_Serial_No_Id"] : DBNull.Value;
                                    serialNumber = TypeConvert.ToBoolean(serialized) ? TypeConvert.ToString(drTemp["Serial_Number"]) : string.Empty;

                                    CreateInventoryMovement(Type, Subtype, inventory.Rows[0]["RE_Inventory_Id"], drTemp["Product_Id"], serialized, articleNumber, invTransfer.Rows[0]["RE_Storage_Location_Id"], storageLocationCode,
                                        TypeConvert.ToInt32(drTemp["Quantity_Issued"]), "Add", "Inventory Transfer", DBNull.Value, orderId, serialNumberId, serialNumber, DBNull.Value);
                                }
                            }
                        }
                    }
                }
                #endregion

                #region Type:Inventory Receive SubType=Receive
                if (String.Equals(Type, "Inventory Receive") && String.Equals(Subtype, "Received"))
                {
                    if (invTransferRecBatch != null && invTransferRecBatch.Rows.Count > 0)
                    {
                        int index = 0;
                        foreach (DataRow drTemp in invTransferRecBatch.Rows)
                        {
                            inventory = this.DefaultDataAccess.GetDataTable("RE_Inventory for StorageLocation? Product?", new object[] { storageLocationTransit.Rows[0]["RE_Storage_Location_Id"],
                            drTemp["Product_Id"]}, new string[] { });

                            if (inventory != null && inventory.Rows.Count > 0)
                            {
                                DataTable product = this.DefaultDataAccess.GetDataTable("SFA: Products id equal to ?", new object[] { drTemp["Product_Id"] }, "RE_Serialized", "RE_Article_Number");

                                serialized = TypeConvert.ToBoolean(product.Rows[0]["RE_Serialized"]);
                                articleNumber = TypeConvert.ToString(product.Rows[0]["RE_Article_Number"]);
                                storageLocationCode = TypeConvert.ToString(this.DefaultDataAccess.SqlIndex("RE_Storage_Location", "Code_", Id.Create(storageLocationTransit.Rows[0]["RE_Storage_Location_Id"])));

                                serialNumberId = serialized ? drTemp["Product_Serial_No_Id"] : DBNull.Value;
                                serialNumber = serialized ? TypeConvert.ToString(this.DefaultDataAccess.SqlIndex("RE_Product_Serial_No", "Serial_Number", Id.Create(drTemp["Product_Serial_No_Id"]))) : String.Empty; 

                                DataTable invTransRecBatch = this.DefaultDataAccess.GetDataTable("RE Inv Transfer Rec Batch for InvTransfer Id and Recieve Batch?",
                                        new object[] { orderId, invTransfer.Rows[0]["Receive_Batch_ID"] }, new string[] { "RE_Inv_Trnsf_Rec_Batch_Id" });
                                if (invTransRecBatch != null && invTransRecBatch.Rows.Count > 0)
                                {
                                    CreateInventoryMovement(Type, Subtype, inventory.Rows[0]["RE_Inventory_Id"], drTemp["Product_Id"], serialized,
                                        articleNumber, storageLocationTransit.Rows[0]["RE_Storage_Location_Id"], storageLocationCode,
                                        TypeConvert.ToInt32(drTemp["Qty"]), "Subtract", "Inventory Receive", DBNull.Value, orderId, serialNumberId, serialNumber, invTransRecBatch.Rows[index]["RE_Inv_Trnsf_Rec_Batch_Id"]);
                                    index += 0;
                                }
                            }
                        }
                    }
                    if (invTransferRecBatch != null && invTransferRecBatch.Rows.Count > 0)
                    {
                        int index = 0;
                        foreach (DataRow drTemp in invTransferRecBatch.Rows)
                        {
                            if (invTransfer != null && invTransfer.Rows.Count > 0)
                            {
                                inventory = this.DefaultDataAccess.GetDataTable("RE_Inventory for StorageLocation? Product?", new object[] {invTransfer.Rows[0]["To_Storage_Location_Id"],
                                drTemp["Product_Id"]}, new string[] { });
                                if (inventory != null && inventory.Rows.Count > 0)
                                {
                                    DataTable product = this.DefaultDataAccess.GetDataTable("SFA: Products id equal to ?", new object[] { drTemp["Product_Id"] }, "RE_Serialized", "RE_Article_Number");

                                    serialized = TypeConvert.ToBoolean(product.Rows[0]["RE_Serialized"]);
                                    articleNumber = TypeConvert.ToString(product.Rows[0]["RE_Article_Number"]);
                                    storageLocationCode = TypeConvert.ToString(this.DefaultDataAccess.SqlIndex("RE_Storage_Location", "Code_", Id.Create(invTransfer.Rows[0]["To_Storage_Location_Id"])));

                                    serialNumberId = serialized ? drTemp["Product_Serial_No_Id"] : DBNull.Value;
                                    serialNumber = serialized ? TypeConvert.ToString(this.DefaultDataAccess.SqlIndex("RE_Product_Serial_No", "Serial_Number", Id.Create(drTemp["Product_Serial_No_Id"]))) : String.Empty; 

                                    DataTable invTransRecBatch = this.DefaultDataAccess.GetDataTable("RE Inv Transfer Rec Batch for InvTransfer Id and Recieve Batch?",
                                        new object[] { orderId, invTransfer.Rows[0]["Receive_Batch_ID"] }, new string[] { "RE_Inv_Trnsf_Rec_Batch_Id" });
                                    if (invTransRecBatch != null && invTransRecBatch.Rows.Count > 0)
                                    {
                                        CreateInventoryMovement(Type, Subtype, inventory.Rows[0]["RE_Inventory_Id"], drTemp["Product_Id"], serialized,
                                            articleNumber, invTransfer.Rows[0]["To_Storage_Location_Id"], storageLocationCode,
                                            TypeConvert.ToInt32(drTemp["Qty"]), "Add", "Inventory Receive", DBNull.Value, orderId, serialNumberId, serialNumber, invTransRecBatch.Rows[index]["RE_Inv_Trnsf_Rec_Batch_Id"]);
                                        index += 0;
                                    }
                                }
                            }
                        }
                    }
                }
                #endregion

                #region Type:PO Receive SubType=Recieve
                if (String.Equals(Type, "PO Receive") && String.Equals(Subtype, "Received"))
                {
                    if (invTransferRecBatch != null && invTransferRecBatch.Rows.Count > 0)
                    {
                        invTransfer = this.DefaultDataAccess.GetDataTable("RE_Inventory Transfer for Inventory Transfer Id?", new object[] { orderId },
                                new string[] { "To_Storage_Location_Id", "Receive_Batch_ID" });
                        int index = 0;
                        foreach (DataRow drTemp in invTransferRecBatch.Rows)
                        {   
                            if (invTransfer != null && invTransfer.Rows.Count > 0)
                            {
                                inventory = this.DefaultDataAccess.GetDataTable("RE_Inventory for StorageLocation? Product?", new object[] {invTransfer.Rows[0]["To_Storage_Location_Id"],
                                drTemp["Product_Id"]}, new string[] { });
                                if (inventory != null && inventory.Rows.Count > 0)
                                {
                                    DataTable product = this.DefaultDataAccess.GetDataTable("SFA: Products id equal to ?", new object[] { drTemp["Product_Id"] }, "RE_Serialized", "RE_Article_Number");

                                    serialized = TypeConvert.ToBoolean(product.Rows[0]["RE_Serialized"]);
                                    articleNumber = TypeConvert.ToString(product.Rows[0]["RE_Article_Number"]);
                                    storageLocationCode = TypeConvert.ToString(this.DefaultDataAccess.SqlIndex("RE_Storage_Location", "Code_", Id.Create(invTransfer.Rows[0]["To_Storage_Location_Id"])));

                                    serialNumberId = serialized ? drTemp["Product_Serial_No_Id"] : DBNull.Value;
                                    serialNumber = serialized ? TypeConvert.ToString(this.DefaultDataAccess.SqlIndex("RE_Product_Serial_No", "Serial_Number", Id.Create(drTemp["Product_Serial_No_Id"]))) : String.Empty;
                                    if (serialized && serialNumberId == DBNull.Value)
                                    {
                                        serialNumber = TypeConvert.ToString(drTemp["Serial_Number"]);
                                    }
                                    DataTable invTransRecBatch = this.DefaultDataAccess.GetDataTable("RE Inv Transfer Rec Batch for InvTransfer Id and Recieve Batch?",
                                        new object[] { orderId, invTransfer.Rows[0]["Receive_Batch_ID"] }, new string[] { "RE_Inv_Trnsf_Rec_Batch_Id" });
                                    if (invTransRecBatch != null && invTransRecBatch.Rows.Count > 0)
                                    {
                                        CreateInventoryMovement(Type, Subtype, inventory.Rows[0]["RE_Inventory_Id"], drTemp["Product_Id"], serialized,
                                            articleNumber, invTransfer.Rows[0]["To_Storage_Location_Id"], storageLocationCode,
                                            TypeConvert.ToInt32(drTemp["Qty"]), "Add", "PO Receive", DBNull.Value, orderId, serialNumberId, serialNumber, invTransRecBatch.Rows[index]["RE_Inv_Trnsf_Rec_Batch_Id"]);
                                        index += 1;
                                    }
                                }
                            }
                        }
                    }
                }
                #endregion
            }
            catch (Exception ex)
            {
                throw new PivotalApplicationCoreException(ex.Message, ex);
            }
        }

        //<summary>
        // Creates New Inventory Transfer record
        // </summary>
        // <param name="primaryRow">Primary Row</param>
        // <param name="supplierId">Supplier Id</param>
        [TaskExecute]
        public virtual Id CreateInventoryTransfer(DataTable primaryRow, Id supplierId,Id recordId)
        {
            try
            {
                Int32 totalIssuedQuantity = 0;
                using (DataTable newInventoryTransfer = this.DefaultDataAccess.GetNewDataTable("RE_Inventory_Transfer", new string[] { }))
                {
                    DataRow newInventoryTransferRow = newInventoryTransfer.NewRow();

                    using (DataTable invTransferProduct = this.DefaultDataAccess.GetDataTable("RE Inv Transfer Product for InvTransfer Id and Supplier?", new object[] {TypeConvert.ToDBValue(recordId),
                        TypeConvert.ToDBValue(supplierId) }, new string[] { "Quantity_Issued" }))
                    {

                        for (int i = 0; i < invTransferProduct.Rows.Count; i++)
                        {
                            if (TypeConvert.ToInt32(invTransferProduct.Rows[i][QuantityIssuedFieldName]) > 0)
                                totalIssuedQuantity = totalIssuedQuantity + TypeConvert.ToInt32(invTransferProduct.Rows[i][QuantityIssuedFieldName]);
                        }

                        newInventoryTransferRow["RE_Supplier_Id"] = TypeConvert.ToDBValue(supplierId);
                        //newInventoryTransferRow["RE_Supplier_Code"] = this.DefaultDataAccess.SqlIndex("Company", "RE_Supplier_Code", supplierId);
                        newInventoryTransferRow["Transfer_ID"] = primaryRow.Rows[0]["Transfer_ID"];
                        newInventoryTransferRow["From_Staff_Id"] = primaryRow.Rows[0]["From_Staff_Id"];
                        newInventoryTransferRow["Transfer_Quantity"] = totalIssuedQuantity;
                        newInventoryTransferRow["Issue_Date"] = DateTime.Now;
                        newInventoryTransferRow["RMA_Status"] = primaryRow.Rows[0]["RMA_Status"];
                        newInventoryTransferRow["Remarks_1"] = primaryRow.Rows[0]["Remarks_1"];
                        newInventoryTransferRow["Remarks_2"] = primaryRow.Rows[0]["Remarks_2"];
                        newInventoryTransferRow["From_Storage_Location_Id"] = primaryRow.Rows[0]["From_Storage_Location_Id"];
                        newInventoryTransferRow["To_Storage_Location_Id"] = primaryRow.Rows[0]["To_Storage_Location_Id"];
                        newInventoryTransferRow["Transfer_Type"] = "RMA";
                        newInventoryTransfer.Rows.Add(newInventoryTransferRow);

                        DataTable invTransfer = this.DefaultDataAccess.SaveDataTable(newInventoryTransfer);

                        AssignProducts(supplierId, recordId, invTransfer);
                        processInventory("RMA", "Issue", invTransfer.Rows[0]["RE_Inventory_Transfer_Id"]);
                        //Commented out temporarily
                        //bool emailSent = CreateReport(invTransfer.Rows[0]["RE_Inventory_Transfer_Id"]);
                        return Id.Create(invTransfer.Rows[0]["RE_Inventory_Transfer_Id"]);
                    }
                }
            }
            catch(Exception ex)
            {
                throw new PivotalApplicationCoreException(ex.Message,ex);
            }
            
        }

        [TaskExecute]
        public virtual void CreateInventoryTransferSerial(object recordId,DataTable primary)
        {
            try
            {
                using (DataTable newInventoryTransferSerial = this.DefaultDataAccess.GetNewDataTable("RE_Inventory_Transfer_Serial", new string[] { }))
                {
                    using (DataTable invTransferProduct = this.DefaultDataAccess.GetDataTable("RE Inv Transfer Products for InvTransfer Id? with  Serial Number", new object[] {recordId
                        }, new string[] { }))
                    {
                        if (invTransferProduct != null && invTransferProduct.Rows.Count > 0)
                        {
                            foreach (DataRow temp in invTransferProduct.Rows)
                            {
                                DataRow newInventoryTransferSerialRow = newInventoryTransferSerial.NewRow();
                                //bool serialized = TypeConvert.ToBoolean(this.DefaultDataAccess.SqlIndex("Product", "RE_Serialized", Id.Create(temp["Product_Id"])));
                                string serialNumber = TypeConvert.ToString(this.DefaultDataAccess.SqlIndex("RE_Product_Serial_No", "Serial_Number", Id.Create(temp["RE_Product_Serial_No_Id"])));
                                newInventoryTransferSerialRow["Serial_Number"] = serialNumber;
                                newInventoryTransferSerialRow["RE_Product_Serial_No_Id"] = temp["RE_Product_Serial_No_Id"];
                                newInventoryTransferSerialRow["Receive_Batch_ID"] = primary.Rows[0]["Receive_Batch_ID"];
                                newInventoryTransferSerialRow["Issued"] = true;
                                newInventoryTransferSerialRow["Received"] = false;
                                newInventoryTransferSerial.Rows.Add(newInventoryTransferSerialRow);
                            }
                        }
                        DataTable invTransferSerial = this.DefaultDataAccess.SaveDataTable(newInventoryTransferSerial);
                    }
                }
            }
            catch (Exception ex)
            {
                throw new PivotalApplicationCoreException(ex.Message, ex);
            }

        }

        [TaskExecute]
        public virtual void updatePrimary(Id recordId,Id suppliedId)
        {
            try
            {
                //bool emailSent = false;
                Int32 totalIssuedQuantity = 0;
                DataTable invTransferProduct = this.DefaultDataAccess.GetDataTable("RE Inv Transfer Product for InvTransfer Id and Supplier?", new object[] {TypeConvert.ToDBValue(recordId),
                        TypeConvert.ToDBValue(suppliedId) }, new string[] { "Quantity_Issued" });
                
                for (int i = 0; i < invTransferProduct.Rows.Count; i++)
                {
                    if (TypeConvert.ToInt32(invTransferProduct.Rows[i][QuantityIssuedFieldName]) > 0)
                        totalIssuedQuantity = totalIssuedQuantity + TypeConvert.ToInt32(invTransferProduct.Rows[i][QuantityIssuedFieldName]);
                }

                if (invTransferProduct != null && invTransferProduct.Rows.Count > 0)
                {
                    DataTable invTransfer = this.DefaultDataAccess.GetDataTable("RE_Inventory_Transfer", recordId ,
                                            new string[] { "RE_Supplier_Id", "Transfer_Quantity","Issue_Date" });
                    if (invTransfer != null && invTransfer.Rows.Count > 0)
                    {
                        invTransfer.Rows[0]["RE_Supplier_Id"] = TypeConvert.ToDBValue(suppliedId);
                        invTransfer.Rows[0]["Transfer_Quantity"] = totalIssuedQuantity;
                        invTransfer.Rows[0]["Issue_Date"] = DateTime.Now;
                    }
                    this.DefaultDataAccess.SaveDataTable(invTransfer);

                }
                processInventory("RMA", "Issue", TypeConvert.ToDBValue(recordId));
                //bool emailSent = CreateReport(TypeConvert.ToDBValue(recordId));
                //return emailSent;
            }
            catch (Exception ex)
            {
                throw new PivotalApplicationCoreException(ex.Message, ex);
            }
        }

        private void AssignProducts(Id supplierId,Id recordId, DataTable invTransfer)
        {
            try
            {
                using (DataTable invTransferProduct = this.DefaultDataAccess.GetDataTable("RE Inv Transfer Product for InvTransfer Id and Supplier?", new object[] {TypeConvert.ToDBValue(recordId),
                        TypeConvert.ToDBValue(supplierId) }, new string[] { "RE_Inventory_Transfer_Id" }))
                {
                    if (invTransferProduct != null && invTransferProduct.Rows.Count > 0)
                    {
                        foreach (DataRow invTemp in invTransferProduct.Rows)
                        {
                            invTemp["RE_Inventory_Transfer_Id"] = invTransfer.Rows[0]["RE_Inventory_Transfer_Id"];
                        }
                    }
                    this.DefaultDataAccess.SaveDataTable(invTransferProduct);
                }

                //DataTable invTransferProduct = this.DefaultDataAccess.GetNewDataTable("RE_Inv_Transfer_Product",new string[]{});

                ////DataTable transferProds = this.DefaultDataAccess.GetDataTable("RE_Inv_Transfer_Product",new string[]{});
                ////IEnumerable<DataRow> query = from order in recordId.AsEnumerable()
                ////                                     select order;
                ////transferProds=query.CopyToDataTable<DataRow>();
                //if (recordId != null && recordId.Rows.Count > 0)
                //{
                //    IEnumerable<DataRow> query = from order in recordId.AsEnumerable()
                //                                     where Id.Create(order.Field<byte[]>("Product_Id__RE_Supplier_Id")) == supplierId
                //                                     select order;
                //    foreach (DataRow invTemp in query)
                //    {
                //        DataRow newinvTransferProductDataRow = invTransferProduct.NewRow();
                //        newinvTransferProductDataRow["RE_Inventory_Transfer_Id"] = invTransfer.Rows[0]["RE_Inventory_Transfer_Id"];
                //        newinvTransferProductDataRow["Product_Id"] = invTemp["Product_Id"];
                //        newinvTransferProductDataRow["RE_Product_Serial_No_Id"] = invTemp["RE_Product_Serial_No_Id"];
                //        newinvTransferProductDataRow["Quantity_Issued"] = invTemp["Quantity_Issued"];

                //        invTransferProduct.Rows.Add(newinvTransferProductDataRow);
                //        //this.DefaultDataAccess.SaveDataRow(invTemp);
                //    }
                //}
                //this.DefaultDataAccess.SaveDataTable(invTransferProduct);
            }
            catch (Exception ex)
            {
                throw new PivotalApplicationCoreException(ex.Message, ex);
            }
        }

      
        //<summary>
        // Creates New Product Serial Number record
        // </summar>y
        [TaskExecute]
        public virtual bool CreateReport(Id recordId)
        {
            try
            {
                bool emailSent = false;
                EmailMessageAttachment attachment;
                string emailMessageId = string.Empty;
                SystemReport objS = this.SystemServer.GetMetaItem<SystemReport>("RE_Print RMA");
                ReportRunner objRunner = this.SystemServer.CreateReportRunner(objS);
                objRunner.ReportJoinType = ReportJoinType.Inner;
                objRunner.ReportOutputFormat = ReportOutputFormat.Pdf;
                byte[] reportReturned = objRunner.Run(ReportFilter.SingleRow, Id.Create(recordId), null);

                DataRow invtransferRow = this.DefaultDataAccess.GetDataRow("RE_Inventory_Transfer", Id.Create(recordId), new string[] { "RMA_Issue_Email_Sent", "Transfer_Document", "RE_Supplier_Id" });
                string email = TypeConvert.ToString(this.DefaultDataAccess.SqlIndex("Company", "Email", Id.Create( invtransferRow["RE_Supplier_Id"])));
                
                DataTemplate dataTemplate = this.SystemServer.GetMetaItem<DataTemplate>("RE_RMA");
                Column attachmentColumn = dataTemplate.PrimaryDataSection.Table.Columns["Transfer_Document"];
                AttachmentInformation attachInfo = this.SystemServer.AttachmentService.GetAttachmentInformation(attachmentColumn, invtransferRow);
                attachInfo.SetAttachment("RMA-Issue" + ".pdf", reportReturned, DateTime.Today.Date);

                if (!string.IsNullOrEmpty(email))
                {
                    EmailMessage emailMessage = this.SystemServer.CreateMessage();
                    emailMessage.To.Add(email);
                    emailMessage.Subject = this.DefaultResourceBundle.GetString("RMA Email Subject");
                    emailMessage.IsBodyHtml = true;
                    emailMessage.Body = this.DefaultResourceBundle.GetString("RMA Email Body");
                    attachment = new EmailMessageAttachment(reportReturned, "RMA-Issue"+".pdf");
                    emailMessage.Attachments.Add(attachment);
                    try
                    {
                        emailMessage.Send();
                    }
                    catch { }
                    emailMessageId = emailMessage.MessageId;
                }

                if (!String.IsNullOrEmpty(emailMessageId))
                {
                    invtransferRow["RMA_Issue_Email_Sent"] = true;
                    emailSent = true;
                }
                else
                {
                    invtransferRow["RMA_Issue_Email_Sent"] = false;
                    emailSent = false;
                }
                this.DefaultDataAccess.SaveDataRow(invtransferRow);
                return true;
            }
            catch (Exception ex)
            {
                throw new PivotalApplicationCoreException(ex.Message, ex);
            }
        }


        //private void SetInventoryTransferProductValues(ref DataRow newInvTransferProduct, Id invTransferProdId)
        //{
        //    try
        //    {
        //        DataTable origTransProd = this.DefaultDataAccess.GetDataTable(REInvTransferProductTableName, invTransferProdId, new string[] { QuantityIssuedFieldName,
        //            QuantityReceivedFieldName, QuantityOpenFieldName, ProductIdFieldName, ProductSKUIdFieldName, FromStorageLocationIdFieldName, ToStorageLocationIdFieldName,
        //            ProductBarCodeFieldName});
        //        const string ColorFieldName = "Color";
        //        const string SizeFieldName = "Size";
        //        //RE_Color & RE_Size table
        //        const string REColorTableName = "RE_Color";
        //        const string RESizeTableName = "RE_Size";
        //        const string DescriptionFieldName = "Description";
        //        if (origTransProd != null)
        //        {
        //            if (origTransProd.Rows.Count > 0)
        //            {
        //                //newInvTransferProduct[QuantityIssuedFieldName] = origTransProd.Rows[0][QuantityIssuedFieldName];
        //                //newInvTransferProduct[QuantityReceivedFieldName] = origTransProd.Rows[0][QuantityReceivedFieldName];
        //                //newInvTransferProduct[QuantityOpenFieldName] = origTransProd.Rows[0][QuantityOpenFieldName];
        //                newInvTransferProduct[QuantityIssuedFieldName] = 1;
        //                newInvTransferProduct[QuantityReceivedFieldName] = 0;
        //                newInvTransferProduct[QuantityOpenFieldName] = -1;
        //                newInvTransferProduct[ProductIdFieldName] = origTransProd.Rows[0][ProductIdFieldName];
        //                newInvTransferProduct[ProductSKUIdFieldName] = origTransProd.Rows[0][ProductSKUIdFieldName];
        //                newInvTransferProduct[ProductBarCodeFieldName] = origTransProd.Rows[0][ProductBarCodeFieldName];
        //                newInvTransferProduct[FromStorageLocationIdFieldName] = origTransProd.Rows[0][FromStorageLocationIdFieldName];
        //                newInvTransferProduct[ToStorageLocationIdFieldName] = origTransProd.Rows[0][ToStorageLocationIdFieldName];
        //                newInvTransferProduct[ProductIdFieldName + Symbol + RnDescriptorFieldName] = DefaultDataAccess.SqlIndex(ProductTableName, RnDescriptorFieldName, Id.Create(origTransProd.Rows[0][ProductIdFieldName]));
        //                newInvTransferProduct[ProductSKUIdFieldName + Symbol + RnDescriptorFieldName] = DefaultDataAccess.SqlIndex("RE_Product_SKU", RnDescriptorFieldName, Id.Create(origTransProd.Rows[0][ProductSKUIdFieldName]));
        //                newInvTransferProduct[ColorFieldName] = DefaultDataAccess.SqlIndex(REColorTableName, DescriptionFieldName,
        //                                                        Id.Create(DefaultDataAccess.SqlIndex("RE_Product_SKU", "Color_Id", Id.Create(origTransProd.Rows[0][ProductSKUIdFieldName]))));
        //                newInvTransferProduct[SizeFieldName] = DefaultDataAccess.SqlIndex(RESizeTableName, DescriptionFieldName,
        //                                                        Id.Create(DefaultDataAccess.SqlIndex("RE_Product_SKU", "Size_Id", Id.Create(origTransProd.Rows[0][ProductSKUIdFieldName]))));
        //            }
        //        }
        //    }
        //    catch (Exception exc)
        //    {
        //        throw new PivotalApplicationCoreException(exc.Message, exc);
        //    }
        //}


        //private void CreateCopyofTransferProducts(ref DataTable transferProductDataTable, Id invTransferProdId)
        //{
        //    try
        //    {
        //        DataTable origTransProd = this.DefaultDataAccess.GetDataTable("RE All Inv Transfer Product for InvTransfer Id?", invTransferProdId,
        //                                new string[] { QuantityIssuedFieldName ,QuantityReceivedFieldName, QuantityOpenFieldName ,ProductIdFieldName,
        //                                ProductSKUIdFieldName, FromStorageLocationIdFieldName, ToStorageLocationIdFieldName , ProductBarCodeFieldName});

        //        if (origTransProd != null && origTransProd.Rows.Count > 0)
        //        {
        //            for (int i = 0; i < origTransProd.Rows.Count; i++)
        //            {
        //                DataRow newInvTransferProduct = transferProductDataTable.NewRow();

        //                newInvTransferProduct[QuantityIssuedFieldName] = origTransProd.Rows[i][QuantityIssuedFieldName];
        //                //NN 12 Mar 2012: Changed code so that it will work for records with Status = Received
        //                newInvTransferProduct[QuantityReceivedFieldName] = 0;
        //                newInvTransferProduct[QuantityOpenFieldName] = 0 - TypeConvert.ToInt32(origTransProd.Rows[i][QuantityIssuedFieldName]);
        //                newInvTransferProduct[ProductIdFieldName] = origTransProd.Rows[i][ProductIdFieldName];
        //                newInvTransferProduct[ProductSKUIdFieldName] = origTransProd.Rows[i][ProductSKUIdFieldName];
        //                newInvTransferProduct[ProductBarCodeFieldName] = origTransProd.Rows[i][ProductBarCodeFieldName];
        //                newInvTransferProduct[FromStorageLocationIdFieldName] = origTransProd.Rows[i][FromStorageLocationIdFieldName];
        //                newInvTransferProduct[ToStorageLocationIdFieldName] = origTransProd.Rows[i][ToStorageLocationIdFieldName];
        //                newInvTransferProduct[ProductIdFieldName + Symbol + RnDescriptorFieldName] = DefaultDataAccess.SqlIndex(ProductTableName,
        //                    RnDescriptorFieldName, Id.Create(origTransProd.Rows[i][ProductIdFieldName]));

        //                newInvTransferProduct[ProductSKUIdFieldName + Symbol + RnDescriptorFieldName] = DefaultDataAccess.SqlIndex("RE_Product_SKU",
        //                    RnDescriptorFieldName, Id.Create(origTransProd.Rows[i][ProductSKUIdFieldName]));
        //                newInvTransferProduct[ColorFieldName] = DefaultDataAccess.SqlIndex(REColorTableName, DescriptionFieldName,
        //                    Id.Create(DefaultDataAccess.SqlIndex("RE_Product_SKU", "Color_Id", Id.Create(origTransProd.Rows[i][ProductSKUIdFieldName]))));
        //                newInvTransferProduct[SizeFieldName] = DefaultDataAccess.SqlIndex(RESizeTableName, DescriptionFieldName,
        //                    Id.Create(DefaultDataAccess.SqlIndex("RE_Product_SKU", "Size_Id", Id.Create(origTransProd.Rows[i][ProductSKUIdFieldName]))));
        //                transferProductDataTable.Rows.Add(newInvTransferProduct);
        //            }
        //        }
        //    }
        //    catch (Exception exc)
        //    {
        //        throw new PivotalApplicationCoreException(exc.Message, exc);
        //    }
        //}

        ///// <summary>
        ///// Deletes the Inventory Transfer Products and Creates reverse movements.
        ///// </summary>
        ///// <param name="items">Comma separated transferProductIds.</param>
        //private void DeletePendingInvTransferProductItems(string items)
        //{
        //    try
        //    {
        //        string[] transferProductIds = items.Split(new string[] { "," }, StringSplitOptions.None);
        //        DataTable invTransferProductItems = null;
        //        if (transferProductIds.Length > 0)
        //        {
        //            for (int i = 0; i < transferProductIds.Length; i++)
        //            {
        //                invTransferProductItems = DefaultDataAccess.GetDataTable(REInvTransferProductTableName, Id.Create(transferProductIds.GetValue(i)), ProductIdFieldName,
        //                    ProductSKUIdFieldName, FromStorageLocationIdFieldName, QuantityIssuedFieldName, REInventoryTransferIdFieldName, ToStorageLocationIdFieldName);
        //                if (invTransferProductItems != null && invTransferProductItems.Rows.Count > 0)
        //                {
        //                    DataRow dRow = invTransferProductItems.Rows[0];
        //                    //There is no point in doing transfer movements where the Issue Qty is 0.
        //                    if (TypeConvert.ToInt32(dRow[QuantityIssuedFieldName]) > 0)
        //                    {
        //                        this.CreateInventoryMovement(dRow[REInventoryTransferIdFieldName], dRow[ProductIdFieldName], dRow[ProductSKUIdFieldName],
        //                            dRow[FromStorageLocationIdFieldName], dRow[ToStorageLocationIdFieldName], TypeConvert.ToInt32(dRow[QuantityIssuedFieldName]),
        //                            true, false, "Transfer");
        //                    }
        //                }
        //                this.DefaultDataAccess.DeleteRecord(Id.Create(transferProductIds.GetValue(i)), "RE_Inv_Transfer_Product");
        //            }
        //        }
        //    }
        //    catch (Exception exc)
        //    {
        //        throw new PivotalApplicationCoreException(exc.Message, exc);
        //    }
        //}

        ///// <summary>
        ///// Creates Inventory movement for the transfer done.
        ///// </summary>
        ///// <param name="primaryRecordId">Inventory Transfer Or SFA_Order Id</param>
        ///// <param name="productId">Product record Id</param>
        ///// <param name="productSKUId">RE_Product_SKU record Id</param>
        ///// <param name="fromStorageLocId">Storage Location Id</param>
        ///// <param name="toStorageLocId">Storage Location Id</param>
        ///// <param name="transferQuantity">Quantity thats transferred</param>
        ///// <param name="reverseMove">boolean value which decides the direction - Add or Subtract </param>
        ///// <param name="callFromReceiveForm">boolean value used when this is called from "RE_Goods_Receive" form</param>
        ///// <param name="movementReason">it can be "Sales" Or "Exchange" or "Transfer"</param>
        //private void CreateInventoryMovement(object primaryRecordId, object productId, object productSKUId, object fromStorageLocId,
        //                                    object toStorageLocId, Int32 transferQuantity, bool reverseMove,
        //                                    bool callFromReceiveForm, string movementReason)
        //{
        //    try
        //    {
        //        object transitLocationId = DBNull.Value;
        //        object storeId = DBNull.Value;
        //        object storageLocationId = DBNull.Value;
        //        const string InventoryforSKUAndStorageLocation = "RE_Inventory for SKU? Storage Location?";
        //        object inventoryId = DBNull.Value;
        //        object storageLocForFirstRecord = DBNull.Value;
        //        object storageLocForSecondRecord = DBNull.Value;
        //        DataTable inventoryDT = null;
        //        DataTable location = null;
        //        string direction = string.Empty;

        //        DataTable inventoryMovement = DefaultDataAccess.GetNewDataTable("RE_Inventory_Movement", new string[] { "Direction", "Reason", "Movement_Date", 
        //            "Ref_Inventory_Trnsfr_Id", "Storage_Location_Id", "Product_Id",ProductSKUIdFieldName,"Quantity","Inventory_Id","Ref_Order_Id","Processed"});

        //        DataRow inventoryMovementRow = inventoryMovement.NewRow();
        //        if (reverseMove)
        //        {
        //            inventoryMovementRow["Direction"] = "Add";
        //            direction = "Add";
        //        }
        //        else
        //        {
        //            inventoryMovementRow["Direction"] = "Subtract";
        //            direction = "Subtract";
        //        }

        //        if (callFromReceiveForm)
        //        {
        //            //Get the  store id value of FromStorage location
        //            //storeId = this.DefaultDataAccess.SqlIndex("RE_Storage_Location", "Store_Id", Id.Create(fromStorageLocId));
        //            object lobId = this.DefaultDataAccess.SqlIndex("RE_Storage_Location", "LOB_Id", Id.Create(fromStorageLocId));
        //            location = DefaultDataAccess.GetDataTable("RE Storage Location for Transit location with LOB Id?", new object[] { lobId }, "RE_Storage_Location_Id");

        //            if (location != null && location.Rows.Count > 0)
        //                transitLocationId = location.Rows[0]["RE_Storage_Location_Id"];

        //            storageLocForFirstRecord = transitLocationId;
        //        }
        //        else
        //            storageLocForFirstRecord = fromStorageLocId;

        //        if (productSKUId != DBNull.Value && storageLocForFirstRecord != DBNull.Value)
        //        {
        //            inventoryDT = this.DefaultDataAccess.GetDataTable(InventoryforSKUAndStorageLocation, new object[] { productSKUId, storageLocForFirstRecord },
        //                                                               new string[] { "RE_Inventory_Id", "Quantity_Actual" });
        //            if (inventoryDT != null && inventoryDT.Rows.Count > 0)
        //            {
        //                inventoryId = inventoryDT.Rows[0]["RE_Inventory_Id"];
        //                //RA:20/Aug/2012:Change for Mobile System:Start:
        //                if (!this.SystemServer.SystemInformation.IsMobile)
        //                {
        //                    //Update Inventory for the first Movement record
        //                    if (direction == "Add")
        //                        inventoryDT.Rows[0]["Quantity_Actual"] = TypeConvert.ToInt32(inventoryDT.Rows[0]["Quantity_Actual"]) + Math.Abs(transferQuantity);
        //                    else if (direction == "Subtract")
        //                        inventoryDT.Rows[0]["Quantity_Actual"] = TypeConvert.ToInt32(inventoryDT.Rows[0]["Quantity_Actual"]) - Math.Abs(transferQuantity);

        //                    this.DefaultDataAccess.SaveDataTable(inventoryDT);
        //                }
        //                //RA:20/Aug/2012:Change for Mobile System:End:
        //            }
        //            else
        //                inventoryId = DBNull.Value;
        //        }

        //        inventoryMovementRow["Movement_Date"] = DateTime.Now;
        //        if (movementReason != "Transfer")
        //            inventoryMovementRow["Ref_Order_Id"] = primaryRecordId;
        //        else
        //            inventoryMovementRow["Ref_Inventory_Trnsfr_Id"] = primaryRecordId;

        //        inventoryMovementRow["Reason"] = movementReason;
        //        inventoryMovementRow[ProductIdFieldName] = productId;
        //        inventoryMovementRow[ProductSKUIdFieldName] = productSKUId;
        //        inventoryMovementRow["Quantity"] = Math.Abs(transferQuantity);
        //        inventoryMovementRow["Inventory_Id"] = inventoryId;
        //        inventoryMovementRow["Storage_Location_Id"] = storageLocForFirstRecord;
        //        //RA:20/Aug/2012:Change for Mobile System:Start:
        //        if (this.SystemServer.SystemInformation.IsMobile)
        //            inventoryMovementRow["Processed"] = false;
        //        else
        //            inventoryMovementRow["Processed"] = true;
        //        //RA:20/Aug/2012:Change for Mobile System:End:
        //        inventoryMovement.Rows.Add(inventoryMovementRow);

        //        if (movementReason != "Transfer")
        //        {
        //            //Save only one record for sales
        //            DefaultDataAccess.SaveDataTable(inventoryMovement);
        //            return;
        //        }

        //        //---------------------------------------------------------------

        //        #region 2nd Movement Record Creation
        //        //Setting inventory Id to null
        //        inventoryId = DBNull.Value;
        //        inventoryMovementRow = inventoryMovement.NewRow();

        //        if (reverseMove)
        //        {
        //            inventoryMovementRow["Direction"] = "Subtract";
        //            direction = "Subtract";
        //        }
        //        else
        //        {
        //            inventoryMovementRow["Direction"] = "Add";
        //            direction = "Add";
        //        }

        //        if (callFromReceiveForm)
        //            storageLocForSecondRecord = toStorageLocId;
        //        else
        //        {
        //            //Get the  store id value of FromStorage location
        //            object lobId = this.DefaultDataAccess.SqlIndex("RE_Storage_Location", "LOB_Id", Id.Create(fromStorageLocId));
        //            location = DefaultDataAccess.GetDataTable("RE Storage Location for Transit location with LOB Id?", new object[] { lobId }, "RE_Storage_Location_Id");

        //            if (location != null && location.Rows.Count > 0)
        //                transitLocationId = location.Rows[0]["RE_Storage_Location_Id"];
        //            storageLocForSecondRecord = transitLocationId;
        //        }

        //        if (productSKUId != DBNull.Value && storageLocForSecondRecord != DBNull.Value)
        //        {
        //            inventoryDT = this.DefaultDataAccess.GetDataTable(InventoryforSKUAndStorageLocation, new object[] { productSKUId, storageLocForSecondRecord },
        //                                                               new string[] { "RE_Inventory_Id", "Quantity_Actual" });
        //            if (inventoryDT != null && inventoryDT.Rows.Count > 0)
        //            {
        //                inventoryId = inventoryDT.Rows[0]["RE_Inventory_Id"];
        //                //RA:20/Aug/2012:Change for Mobile System:Start:
        //                if (!this.SystemServer.SystemInformation.IsMobile)
        //                {
        //                    //Update Inventory for the first Movement record
        //                    if (direction == "Add")
        //                        inventoryDT.Rows[0]["Quantity_Actual"] = TypeConvert.ToInt32(inventoryDT.Rows[0]["Quantity_Actual"]) + Math.Abs(transferQuantity);
        //                    else if (direction == "Subtract")
        //                        inventoryDT.Rows[0]["Quantity_Actual"] = TypeConvert.ToInt32(inventoryDT.Rows[0]["Quantity_Actual"]) - Math.Abs(transferQuantity);

        //                    this.DefaultDataAccess.SaveDataTable(inventoryDT);
        //                }
        //                //RA:20/Aug/2012:Change for Mobile System:End:
        //            }
        //            else
        //                inventoryId = DBNull.Value;
        //        }

        //        inventoryMovementRow["Reason"] = movementReason;
        //        inventoryMovementRow["Movement_Date"] = DateTime.Now;

        //        if (movementReason != "Transfer")
        //            inventoryMovementRow["Ref_Order_Id"] = primaryRecordId;
        //        else
        //            inventoryMovementRow["Ref_Inventory_Trnsfr_Id"] = primaryRecordId;

        //        inventoryMovementRow["Storage_Location_Id"] = storageLocForSecondRecord;
        //        inventoryMovementRow[ProductIdFieldName] = productId;
        //        inventoryMovementRow[ProductSKUIdFieldName] = productSKUId;
        //        inventoryMovementRow["Quantity"] = Math.Abs(transferQuantity);
        //        inventoryMovementRow["Inventory_Id"] = inventoryId;
        //        //RA:20/Aug/2012:Change for Mobile System:Start:
        //        if (this.SystemServer.SystemInformation.IsMobile)
        //            inventoryMovementRow["Processed"] = false;
        //        else
        //            inventoryMovementRow["Processed"] = true;
        //        //RA:20/Aug/2012:Change for Mobile System:End:
        //        inventoryMovement.Rows.Add(inventoryMovementRow);

        //        //Save Inventory Movement ( 2 records)
        //        DefaultDataAccess.SaveDataTable(inventoryMovement);
        //        #endregion
        //    }
        //    catch (Exception exc)
        //    {
        //        throw new PivotalApplicationCoreException(exc.Message, exc);
        //    }
        //}

        
        #endregion

        //#region Task Execute Methods

        //[TaskExecute]
        //public virtual void RemovePendingItems(object inventoryTransferId, string invTransProductIds)
        //{
        //    try
        //    {
        //        DeletePendingInvTransferProductItems(invTransProductIds);

        //        DataTable inventTransfer = DefaultDataAccess.GetDataTable("RE_Inventory_Transfer", Id.Create(inventoryTransferId),
        //                        new string[] { TransferQuantityFieldName, ReceivedQuantityFieldName, StatusFieldName });
        //        if (inventTransfer != null && inventTransfer.Rows.Count > 0)
        //        {
        //            DataTable transferProduct = this.DefaultDataAccess.GetDataTable("RE All Inv Transfer Product for InvTransfer Id?", Id.Create(inventoryTransferId),
        //                   new string[] { QuantityIssuedFieldName, QuantityReceivedFieldName, ReceivedFieldName, FromStorageLocationIdFieldName,  
        //                   ToStorageLocationIdFieldName, REInventoryTransferIdFieldName, ProductIdFieldName, ProductSKUIdFieldName});
        //            Int32 totalIssuedQuantity = 0;
        //            Int32 totalReceivedQuantity = 0;
        //            bool received = true;
        //            if (transferProduct != null && transferProduct.Rows.Count > 0)
        //            {
        //                for (int i = 0; i < transferProduct.Rows.Count; i++)
        //                {
        //                    if (TypeConvert.ToInt32(transferProduct.Rows[i][QuantityIssuedFieldName]) > 0)
        //                        totalIssuedQuantity = totalIssuedQuantity + TypeConvert.ToInt32(transferProduct.Rows[i][QuantityIssuedFieldName]);

        //                    if (!TypeConvert.ToBoolean(transferProduct.Rows[i][ReceivedFieldName]))
        //                        received = false;

        //                    if (TypeConvert.ToInt32(transferProduct.Rows[i][QuantityReceivedFieldName]) > 0)
        //                        totalReceivedQuantity = totalReceivedQuantity + TypeConvert.ToInt32(transferProduct.Rows[i][QuantityReceivedFieldName]);
        //                }
        //            }
        //            inventTransfer.Rows[0][TransferQuantityFieldName] = totalIssuedQuantity;
        //            inventTransfer.Rows[0][ReceivedQuantityFieldName] = totalReceivedQuantity;
        //            //After deleting Transfer Product we need to check for the Received status & update the 'Inventory Transfer' accordingly.
        //            //update the total issued & received quantity also after the deletion
        //            if (received)
        //            {
        //                inventTransfer.Rows[0][StatusFieldName] = "Received";

        //                //Create Movement records for the existing items in the grid.
        //                //There is no point in doing transfer movements where the Issue Qty is 0.
        //                foreach (DataRow dr in transferProduct.Rows)
        //                {
        //                    if (TypeConvert.ToInt32(dr[QuantityIssuedFieldName]) > 0)
        //                    {
        //                        this.CreateInventoryMovement(dr[REInventoryTransferIdFieldName], dr[ProductIdFieldName], dr[ProductSKUIdFieldName],
        //                            dr[FromStorageLocationIdFieldName], dr[ToStorageLocationIdFieldName], TypeConvert.ToInt32(dr[QuantityIssuedFieldName]),
        //                            false, true, "Transfer");
        //                    }
        //                }
        //            }

        //            DefaultDataAccess.SaveDataTable(inventTransfer);
        //        }
        //    }
        //    catch (Exception exc)
        //    {
        //        throw new PivotalApplicationCoreException(exc.Message, exc);
        //    }
        //}

        ///// <summary>
        ///// Create Transfer movements for Goods Issued.
        ///// </summary>
        ///// <param name="inventoryTransferId"></param>
        ///// <param name="reverseMovement"></param>
        //[TaskExecute]
        //public virtual void CreateTransferMovementForIssuedRecords(object inventoryTransferId, bool reverseMovement)
        //{
        //    try
        //    {
        //        DataTable invTransferProductItems = null;

        //        invTransferProductItems = DefaultDataAccess.GetDataTable("RE All Inv Transfer Product for InvTransfer Id?", new object[] { inventoryTransferId },
        //                                    new string[] {ProductIdFieldName,ProductSKUIdFieldName,FromStorageLocationIdFieldName,
        //                                            QuantityIssuedFieldName,REInventoryTransferIdFieldName ,ToStorageLocationIdFieldName });
        //        if (invTransferProductItems != null && invTransferProductItems.Rows.Count > 0)
        //        {
        //            for (int i = 0; i < invTransferProductItems.Rows.Count; i++)
        //            {
        //                //There is no point in doing transfer movements where the Issue Qty is 0.
        //                if (TypeConvert.ToInt32(invTransferProductItems.Rows[i][QuantityIssuedFieldName]) > 0)
        //                {
        //                    this.CreateInventoryMovement(invTransferProductItems.Rows[i][REInventoryTransferIdFieldName], invTransferProductItems.Rows[i][ProductIdFieldName],
        //                                                    invTransferProductItems.Rows[i][ProductSKUIdFieldName], invTransferProductItems.Rows[i][FromStorageLocationIdFieldName],
        //                                                     invTransferProductItems.Rows[i][ToStorageLocationIdFieldName], TypeConvert.ToInt32(invTransferProductItems.Rows[i][QuantityIssuedFieldName]),
        //                                                      reverseMovement, false, "Transfer");
        //                }
        //            }
        //        }
        //    }
        //    catch (Exception exc)
        //    {
        //        throw new PivotalApplicationCoreException(exc.Message, exc);
        //    }
        //}

        //[TaskExecute]
        //public virtual void CreateSalesMovementRecord(object orderId)
        //{
        //    try
        //    {
        //        DataTable orderProduct = null;
        //        bool reverseMovement = false;
        //        string reason = "";
        //        orderProduct = DefaultDataAccess.GetDataTable("RE_Order Products with Order ?", new object[] { orderId }, new string[] {ProductIdFieldName,
        //            "RE_Product_SKU_Id","RE_Storage_Location_Id", "Quantity","SFA_Order__Product_Id"  });

        //        string orderStatus = TypeConvert.ToString(DefaultDataAccess.SqlIndex("SFA_Order", "RE_Order_Status", Id.Create(orderId)));
        //        string orderType = TypeConvert.ToString(DefaultDataAccess.SqlIndex("SFA_Order", "RE_Type", Id.Create(orderId)));

        //        if (orderProduct != null && orderProduct.Rows.Count > 0)
        //        {
        //            for (int i = 0; i < orderProduct.Rows.Count; i++)
        //            {
        //                if (orderStatus == VoidOrderStatus)
        //                {
        //                    reason = VoidOrderStatus;
        //                    if (TypeConvert.ToInt32(orderProduct.Rows[i]["Quantity"]) > 0)
        //                        reverseMovement = true;  //Add
        //                    else if (TypeConvert.ToInt32(orderProduct.Rows[i]["Quantity"]) < 0)
        //                        reverseMovement = false; //Subtract
        //                }
        //                else
        //                {
        //                    switch (orderType)
        //                    {
        //                        case OrderType.Sale:
        //                            reason = OrderType.Sale;
        //                            reverseMovement = false; //Subtract
        //                            break;

        //                        case OrderType.Refund:
        //                            reason = OrderType.Refund;
        //                            reverseMovement = true; //Add
        //                            break;

        //                        case OrderType.Exchange:
        //                            reason = OrderType.Exchange;
        //                            if (TypeConvert.ToInt32(orderProduct.Rows[i]["Quantity"]) > 0) //Subtract
        //                                reverseMovement = false;  //Subtract
        //                            else if (TypeConvert.ToInt32(orderProduct.Rows[i]["Quantity"]) < 0)  //Add
        //                                reverseMovement = true;   //Add
        //                            break;
        //                    }
        //                }
        //                if (TypeConvert.ToInt32(orderProduct.Rows[i]["Quantity"]) != 0)
        //                {
        //                    this.CreateInventoryMovement(orderId, orderProduct.Rows[i][ProductIdFieldName], orderProduct.Rows[i]["RE_Product_SKU_Id"],
        //                        orderProduct.Rows[i]["RE_Storage_Location_Id"], DBNull.Value, TypeConvert.ToInt32(orderProduct.Rows[i]["Quantity"]), reverseMovement, false, reason);
        //                }
        //            }
        //        }
        //    }
        //    catch (Exception exc)
        //    {
        //        throw new PivotalApplicationCoreException(exc.Message, exc);
        //    }
        //}
        ///// <summary>
        ///// Link the temp inventory to the main GR Inventory
        ///// </summary>
        ///// <param name="inventoryTransferId"></param>
        ///// <param name="linkInv"></param>
        //[TaskExecute]
        //public virtual void LinktoTempGR(object inventoryTransferId, object linkInv)
        //{
        //    try
        //    {
        //        DataTable inventTransferLink = DefaultDataAccess.GetDataTable("RE_Inventory_Transfer", Id.Create(linkInv),
        //                        new string[] { "Link_Transfer_Id" });

        //        if (inventTransferLink != null && inventTransferLink.Rows.Count > 0)
        //        {
        //            inventTransferLink.Rows[0]["Link_Transfer_Id"] = inventoryTransferId;
        //            DefaultDataAccess.SaveDataTable(inventTransferLink);
        //        }
        //    }
        //    catch (Exception exc)
        //    {
        //        throw new PivotalApplicationCoreException(exc.Message, exc);
        //    }
        //}


        //#endregion
    }
}